Decrytion Error After an elapsed time

Issue #415 invalid
Esteban Suárez created an issue

Hi, I’m using an encrypted and signed JWT to authenticate in a REST API. I’ve built a login POST resource for token acquisition and a request filter for token validation. I can actually generate the token and then correctly decrypt and validate it in the request filter, but after Tomcat server restart, when I try to decrypt the token inside the filter, I’m getting the following exception:

com.nimbusds.jose.JOSEException: Decryption error- Caused by: javax.crypto.BadPaddingException: Decryption error

I was following this example for token generation. I’ve attached the class where I’m generating and validating the token to this message. The exception it’s being triggered in the method called isValidToken, at line 97.

I really appreciate any help you can provide because I couldn’t identify the cause for this issue and I’d like to discard a possible bug in the library.

Comments (5)

  1. Esteban Suárez reporter

    This is the full stack trace of the exception:

    com.nimbusds.jose.JOSEException: Decryption error
            at com.nimbusds.jose.crypto.impl.RSA_OAEP_256.decryptCEK(RSA_OAEP_256.java:123)
            at com.nimbusds.jose.crypto.RSADecrypter.decrypt(RSADecrypter.java:278)
            at com.nimbusds.jose.JWEObject.decrypt(JWEObject.java:415)
            at co.com.zaita.climagroProxy.util.JWTHelper.isValidToken(JWTHelper.java:97)
            at co.com.zaita.climagroProxy.filter.AuthFilter.filter(AuthFilter.java:57)
            at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:132)
            at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:68)
            at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
            at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:318)
            at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
            at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
            at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
            at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
            at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
            at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
            at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
            at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
            at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
            at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
            at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
            at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
            at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
            at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
            at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
            at org.apache.catalina.valves.RequestFilterValve.process(RequestFilterValve.java:348)
            at org.apache.catalina.valves.RemoteAddrValve.invoke(RemoteAddrValve.java:52)
            at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
            at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
            at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
            at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
            at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
            at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:748)
    Caused by: javax.crypto.BadPaddingException: Decryption error
            at sun.security.rsa.RSAPadding.unpadOAEP(RSAPadding.java:502)
            at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:296)
            at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
            at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
            at javax.crypto.Cipher.doFinal(Cipher.java:2164)
            at com.nimbusds.jose.crypto.impl.RSA_OAEP_256.decryptCEK(RSA_OAEP_256.java:115)
            ... 45 common frames omitted
    

  2. Vladimir Dzhuvinov

    The code appears to rely on a key that gets generated statically, at each Tomcat startup.

    After a restart a new key will get generated and the previously will be lost, so trying to decrypt a token meant for the old key will fail.

    My suggestion is to generate a key offline and store it in some config file or pass it via a Java system property (as BASE64 encoded JWK for example).

  3. Esteban Suárez reporter

    @Vladimir Dzhuvinov Thanks for your answer and the suggestion. Would it be possible for you to point me to an example about using the library to consume externally stored keys? I’ll make research anyway but having a specific example could be time-saving

  4. Log in to comment