jwtk / jjwt

Java JWT: JSON Web Token for Java and Android
Apache License 2.0
10.04k stars 1.31k forks source link

java.lang.IllegalArgumentException: Invalid Map 'iv' (Initialization Vector) value: 1230868678. Values must be either String or [B instances. Value type found: java.math.BigInteger. #933

Open Sameer-Jani-201 opened 3 months ago

Sameer-Jani-201 commented 3 months ago

Upgraded 0.11.5 to 0.12.5. Now getting the below error:


Note: It allows only String or ByteArray in the header iv(Initialization Vector) value. In the previous version, it was allowed to pass BigInteger for IV value in the header.

java.lang.IllegalArgumentException: Invalid Map 'iv' (Initialization Vector) value: 1230868678. Values must be either String or [B instances. Value type found: java.math.BigInteger. at io.jsonwebtoken.impl.ParameterMap.apply(ParameterMap.java:193) at io.jsonwebtoken.impl.ParameterMap.put(ParameterMap.java:139) at io.jsonwebtoken.impl.ParameterMap.put(ParameterMap.java:149) at io.jsonwebtoken.impl.ParameterMap.put(ParameterMap.java:36) at io.jsonwebtoken.impl.lang.DelegatingMap.put(DelegatingMap.java:81) at io.jsonwebtoken.impl.lang.DelegatingMapMutator.add(DelegatingMapMutator.java:45) at com.xxx.utils.CipherUtils.generateDPOPToken(CipherUtils.kt:107) at com.xxx.SessionManager.doLoginOrRefreshToken(SessionManager.kt:48) at com.xxx.central.RequestHandler.requestLogin(RequestHandler.kt:5352) at com.xxx.central.RequestHandler.access$requestLogin(RequestHandler.kt:245) at com.xxx.central.RequestHandler$doGatewayLogin$1.invokeSuspend(RequestHandler.kt:5174) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664) Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@91ec9a8, Dispatchers.IO] Caused by: java.lang.IllegalArgumentException: Values must be either String or [B instances. Value type found: java.math.BigInteger. at io.jsonwebtoken.impl.lang.EncodedObjectConverter.applyFrom(EncodedObjectConverter.java:46) at io.jsonwebtoken.impl.lang.RequiredBitLengthConverter.applyFrom(RequiredBitLengthConverter.java:57) at io.jsonwebtoken.impl.lang.RequiredBitLengthConverter.applyFrom(RequiredBitLengthConverter.java:20) at io.jsonwebtoken.impl.lang.DefaultParameter.applyFrom(DefaultParameter.java:124) at io.jsonwebtoken.impl.ParameterMap.apply(ParameterMap.java:176) ... 18 more

bdemers commented 3 months ago

Can you include the full stacktrace (specifically the "18 more" part)

lhazlewood commented 3 months ago

The JWE iv header is required by the JWA specification to be a Base64Url-encoded 96 bit byte array:

https://www.rfc-editor.org/rfc/rfc7518.html#section-4.7.1.1

Cryptographic initialization vectors are always bit strings (i.e. byte arrays), and should always be randomly generated. It's unclear to me how a randomly-generated IV would ever need to be wrapped as a BigInteger. To help us understand what might be going on, how/why is the IV being created that way? Thanks!

Sameer-Jani-201 commented 3 months ago

We are sending the IV value in BigInteger because our cloud expects the same in Integer. Hence We need to convert 16 bytes iv byte array to BigInteger to send it to the cloud. Below is the overall IV and JWT token generation process :

1) We are creating a Byte array of 16 bytes and then appending random integer values to that array with Big-Endian order. (here, 4 bytes of Integer value and others are 0's)

2) Encrypting our other data using AES 128 CTR with No Padding using the same IV.

3) In the JWT header we are passing that IV as BigInteger with the help of the BigInteger(iv) construction method. (Here, iv is a byte array)

This was working for us in the previous version which was 0.11.5.

Please let me know what would be the better solution for it.

lhazlewood commented 2 months ago

@Sameer-Jani-201 are you creating a JWS? Do you have an example of how you're building the JWS so we can see what JJWT methods are being called?