Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT not working on Android #744

Closed
t0in4 opened this issue Jun 4, 2022 · 36 comments
Closed

JWT not working on Android #744

t0in4 opened this issue Jun 4, 2022 · 36 comments

Comments

@t0in4
Copy link

t0in4 commented Jun 4, 2022

Describe the bug
Code on Android it gives an error - Caused by: io.jsonwebtoken.security.SignatureException: Unavailable RSA Signature algorithm 'RSASSA-PSS'. code on Android

But same code in IntelliJ Idea console return a valid JWT token. code on IntelliJ Idea

Sometimes, when i launch first time after reload an Android code, it return a JWT token but when i check it - it is not valid token. (service return )

I check the correctness of token by free service https://reqbin.com/

To Reproduce
Steps to reproduce the behavior after gain a JWT token from Android:

  1. On reqbin site - fill the site address field https://iam.api.cloud.yandex.net/iam/v1/tokens
  2. then in content field write {"jwt": "eyJraWQiOiJhamU5MmRwYzR0NHR1N2JidTh1biIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJhamVpanAxOW01OTlzOGFvczZ2ciIsImF1ZCI6Imh0dHBzOlwvXC9pYW0uYXBpLmNsb3VkLnlhbmRleC5uZXRcL2lhbVwvdjFcL3Rva2VucyIsImlhdCI6MTY1NDMxNDE4MywiZXhwIjoxNjU0MzE0NTQzfQ.aStQNvR1r8tLQyJRTAo-JkRhXTmcLRfYGohktpKmRUofG1uTsX-t-Ci3-HEOdkIYbQUE-esA9hWYgL8Q5Vx7QIaDVNZ2G_RHeHYi9oTwsnCgt-1CgC9Xat4WgjJ_7gUKajpUXPmuDxvXLt5vZhVhM9-03eUSRSAofxjmue-_qW_5ihtxOi5lgmRmAu34AmUvusupgQLdjjGT75m29lvlXPj2bH-vUczgabNzXQH8ZkA8AilByP8mHmzHxd-cBSXvW7wqbdNeVRPKBU8Gbd8Htkl5zDA3d-RKwQ0vbwOudp2kEo-Okx8gvRFqiMdx3wTEohTT9j6A0BKu6VQQEAuaeg")
  3. then press "SEND" button
  4. it return a message with error { "message": "Only the 'PS256' algorithms is currently supported for JWT"}

Expected behavior
When i check JWT token from IntelliJ Idea console
the reqbin site return a message "iamToken": "t1.9euelZrHnceSj4uPjsmQnZKUlJeMzu3rnpWalpWPzsaSysbGjMeekIzJiY3l8_d9KRJr-e9nezht_d3z9z1YD2v572d7OG39zef1656VmsbNm4-cy4vLi4rInZ2Kx4qR7_0.WrOA-radhm9TNJvaoBcccf3-qku_KvPHpxQ9Livfdjb8DUonpXcGZ6KFB1xCIvn8iMRclFAl1kbrUrKfZ60LDw"

Screenshots
If applicable, add screenshots to help explain your problem.

IntelliJ Idea valid token
Screenshot from 2022-06-04 17-25-18

Android Studio non valid token
Screenshot from 2022-06-04 17-25-54

Android Studio error
Screenshot from 2022-06-04 17-26-20

Server Answers
Screenshot from 2022-06-04 17-26-49

Screenshot from 2022-06-04 17-28-03

@lhazlewood
Copy link
Contributor

lhazlewood commented Jun 4, 2022

Hello!

I check the correctness of token by free service https://reqbin.com/

The reqbin site or yandex.net are not canonical authorities on the correctness of JWT tokens - I wouldn't necessarily trust either one of them for correctness. It appears they don't support PS384 or PS512, so clearly they don't implement the full specification. In other words, I trust JJWT (which does implement the full JWS specification) more than I trust either of those two sources.

Anyway, from the JJWT documentation's Features section:

image

RSASSA-PSS algorithms are only available on JDK >= 11 natively. If not on JDK >= 11, you can add BouncyCastle to the runtime classpath, and that will support RSASSA-PSS algorithms.

What JDK were you using in IntelliJ?

Did you enable BouncyCastle or SpongyCastle in Android?

I hope that helps! Please let us know!

@t0in4
Copy link
Author

t0in4 commented Jun 5, 2022

Hello!
Thank you for response. I am very appreciated.

IntelliJ logs:
2021-11-26 13:57:34,958 [ 516] INFO - #com.intellij.idea.Main - IDE: IntelliJ IDEA (build #IC-212.5284.40, 14 Sep 2021 01:29)
2021-11-26 13:57:34,968 [ 526] INFO - #com.intellij.idea.Main - OS: Linux (5.10.0-9-amd64, amd64)
2021-11-26 13:57:35,028 [ 586] INFO - #com.intellij.idea.Main - JRE: 11.0.12+7-b1504.28 (JetBrains s.r.o.)
2021-11-26 13:57:35,031 [ 589] INFO - #com.intellij.idea.Main - JVM: 11.0.12+7-b1504.28 (OpenJDK 64-Bit Server VM)

Android Studio logs:
2022-05-25 19:30:23,640 [18664866] ERROR - aemon.impl.PassExecutorService - Android Studio Arctic Fox | 2020.3.1 Patch 4 Build #AI-203.7717.56.2031.7935034
2022-05-25 19:30:23,640 [18664866] ERROR - aemon.impl.PassExecutorService - JDK: 11.0.10; VM: OpenJDK 64-Bit Server VM; Vendor: JetBrains s.r.o.
2022-05-25 19:30:23,640 [18664866] ERROR - aemon.impl.PassExecutorService - OS: Linux

Yes, I add BouncyCastle in gradle.build for Android and for IntelliJ
Screenshot from 2022-06-05 16-18-04

@t0in4
Copy link
Author

t0in4 commented Jun 5, 2022

Just now, changed Android Studio jdk from 11.0.10 to 11.0.12
2022-06-05 16:41:57,218 [2371087] INFO - STDOUT - Current JDK's:
2022-06-05 16:41:57,220 [2371089] INFO - STDOUT - 11: /usr/lib/jvm/jdk-11.0.12

and the error is same as on jdk 11.0.10 - Caused by: io.jsonwebtoken.security.SignatureException: Unavailable RSA Signature algorithm 'RSASSA-PSS'.
And jdk 11.0.12 - don't return any token in logs.
jdk 11.0.10 return token which don't valid to gain yandex iam_token

@t0in4
Copy link
Author

t0in4 commented Jun 5, 2022

added bcprov-ext-jdk18on-171.jar (BouncyCastle last jar - implementation files('libs/bcprov-ext-jdk18on-171.jar') as a library in Android Studio,
(and commented //implementation("org.bouncycastle:bcpkix-jdk15to18:1.71" in gradle.build)
but mistake is the same

2022-06-05 17:24:36.890 3053-3053/com.eyehail.smallproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.eyehail.smallproject, PID: 3053
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.eyehail.smallproject/com.eyehail.smallproject.MainActivity}: io.jsonwebtoken.security.SignatureException: Unavailable RSA Signature algorithm 'RSASSA-PSS'.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: io.jsonwebtoken.security.SignatureException: Unavailable RSA Signature algorithm 'RSASSA-PSS'.
at io.jsonwebtoken.impl.crypto.SignatureProvider.createSignatureInstance(SignatureProvider.java:68)
at io.jsonwebtoken.impl.crypto.RsaProvider.createSignatureInstance(RsaProvider.java:69)
at io.jsonwebtoken.impl.crypto.RsaSigner.doSign(RsaSigner.java:53)
at io.jsonwebtoken.impl.crypto.RsaSigner.sign(RsaSigner.java:43)
at io.jsonwebtoken.impl.crypto.DefaultJwtSigner.sign(DefaultJwtSigner.java:59)
at io.jsonwebtoken.impl.DefaultJwtBuilder.compact(DefaultJwtBuilder.java:344)
at com.eyehail.smallproject.MainActivity.getJWT(MainActivity.kt:60)
at com.eyehail.smallproject.MainActivity.onCreate(MainActivity.kt:24)
at android.app.Activity.performCreate(Activity.java:7825)
at android.app.Activity.performCreate(Activity.java:7814)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
at android.os.Handler.dispatchMessage(Handler.java:107) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7356) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
Caused by: java.security.NoSuchAlgorithmException: RSASSA-PSS Signature not available
at java.security.Signature.getInstance(Signature.java:363)
at io.jsonwebtoken.impl.crypto.SignatureProvider.getSignatureInstance(SignatureProvider.java:73)
at io.jsonwebtoken.impl.crypto.SignatureProvider.createSignatureInstance(SignatureProvider.java:62)
at io.jsonwebtoken.impl.crypto.RsaProvider.createSignatureInstance(RsaProvider.java:69) 
at io.jsonwebtoken.impl.crypto.RsaSigner.doSign(RsaSigner.java:53) 
at io.jsonwebtoken.impl.crypto.RsaSigner.sign(RsaSigner.java:43) 
at io.jsonwebtoken.impl.crypto.DefaultJwtSigner.sign(DefaultJwtSigner.java:59) 
at io.jsonwebtoken.impl.DefaultJwtBuilder.compact(DefaultJwtBuilder.java:344) 
at com.eyehail.smallproject.MainActivity.getJWT(MainActivity.kt:60) 
at com.eyehail.smallproject.MainActivity.onCreate(MainActivity.kt:24) 
at android.app.Activity.performCreate(Activity.java:7825) 
at android.app.Activity.performCreate(Activity.java:7814) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
at android.os.Handler.dispatchMessage(Handler.java:107) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7356) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

@lhazlewood
Copy link
Contributor

You may not have the correct dependency. Our documentation shows:

// Uncomment the next line if you want to use RSASSA-PSS (PS256, PS384, PS512) algorithms:
//'org.bouncycastle:bcprov-jdk15on:1.70',

@lhazlewood
Copy link
Contributor

From our Android documentation:

image

Try the org.bouncycastle:bcprov-jdk15on:1.70 and see if that helps.

@t0in4
Copy link
Author

t0in4 commented Jun 6, 2022

Hello!
Output still give a same error
Screenshot from 2022-06-06 19-20-38

Maybe, i need specific version of Android Studio?

@lhazlewood
Copy link
Contributor

Out of curiosity, what if you explicitly registered the BouncyCastle provider in your code first, before using JJWT? For example:

Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(provider);

Does that fix it?

If not, is there a sample project you could provide for us to test with? I am unable to reproduce the problem.

@t0in4
Copy link
Author

t0in4 commented Jun 7, 2022

Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(provider);

doesn't fix..

sample project on Android - https://github.com/t0in4/small_project

the same working project IntelliJ - https://github.com/t0in4/simple_project_intellij

@bdemers
Copy link
Member

bdemers commented Jun 7, 2022

It looks like current versions of Android do not support RSASSA-PSS
https://developer.android.com/reference/java/security/Signature

Similar to what @lhazlewood mentioned, you would need to add a Provider that has that capability.

It looks like we can narrow things down to the call of Signature.getInstance("RSASSA-PSS")
https://docs.oracle.com/javase/7/docs/api/java/security/Signature.html#getInstance(java.lang.String)

I'd suggest trying the following in your environment:

java.security.Signature.getInstance("RSASSA-PSS")

I'd expect the above to fail with the same exception:

Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(provider);

java.security.Signature.getInstance("RSASSA-PSS", "BC");
// and/or 
java.security.Signature.getInstance("RSASSA-PSS", Security.getProvider("BC"));

Does this work?

@t0in4
Copy link
Author

t0in4 commented Jun 7, 2022

Hello!
not working
Output for both variants
Caused by: java.security.NoSuchAlgorithmException: no such algorithm: RSASSA-PSS for provider BC

@lhazlewood
Copy link
Contributor

I think Android might ship with their own old/deprecated BC provider. Try removing that and adding yours:

public class MyApplication extends Application {
    static {
        Security.removeProvider("BC");
        Security.addProvider(new new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }
}

@t0in4
Copy link
Author

t0in4 commented Jun 8, 2022

Hello!
Still not working, maybe Android somehow prohibited to use bouncy castle?

@bdemers
Copy link
Member

bdemers commented Jun 8, 2022

@t0in4 possibly.

If we have narrowed it down to a Signature.getInstance() call, that means the issue isn't something in JJWT.

You might bet better insight into the problem on an Android-specific forum or Stack Overflow.

It sounds like you are only attempting to use PS256 because it works with https://reqbin.com/ ? If so I'd suggest using another tool for debugging (sorry, I know that isn't a very helpful suggestion)

All that said, I DO think we should to document your findings on this issue in the JJWT readme if you can get a definitive answer on what is going on here. Potentially also add some sort of nice error message.
We could detect the NoSuchAlgorithmException and the OS info (e.g. some version of Android) and add a log message pointing the developer in the right direction 🤔

@lhazlewood
Copy link
Contributor

lhazlewood commented Jun 8, 2022

I don't know what the issue is either - lots of answers on StackOverflow say BouncyCastle works just fine with Android, especially for anything after 2018 that I could find. My last suggestion of removing the provider and then manually adding it back in seems to work for others on Android.

I would definitely ask on StackOverflow.com and see if anyone with more Android expertise can help. If you or anyone else reading this finds a solution, please do reply and let us know what it is so we can add it to the JJWT documentation. We would be grateful! 🙏

@t0in4
Copy link
Author

t0in4 commented Jun 8, 2022

Thank you, I am very appreciated for your responses.
Answers are really helpful and i learn many new. Thank you!

Just now, i check one more time - and i got an output without errors but token still cannot validated by yandex service
Screenshot from 2022-06-08 21-24-25

https://github.com/t0in4/small_project/tree/working_but_with_jwt_validation_fails
And the error is "JWT signature validation fails", as i think, in Android implementation of PS256

Becouse, the same code, but written in IntelliJ is working and pass JWT signature validation from yandex side
Screenshot from 2022-06-08 21-58-03

https://github.com/t0in4/simple_project_intellij

It sounds like you are only attempting to use PS256 because it works with https://reqbin.com/ ?

No, i try to use yandex translate service - and yandex iam_token is expires in 12 hours (and in official documentation, they recomend to gain new iam_token every hour), so i need to call it often from application.
Usually, it is possible to call iam_token directly with a help of yandex_oath_id.
But more secure to call iam_token from the "service account" side (something like one more entity).
And one method for gain iam_token is with help of jwt.
I am using reqbin site becouse it is easy to quick check the validation of post request.

Thank you one more time!

@lhazlewood
Copy link
Contributor

as i think, in Android implementation of PS256

Yes, something is weird here. Please do ask on StackOverflow why this is the case. It seems like you should be able to swap out their implementation for your own BouncyCastle instance, but I'm not sure how to do that beyond what I've suggested already. Hopefully some Android experts can advise.

@t0in4
Copy link
Author

t0in4 commented Jun 8, 2022

Ok, i will try to ask on StackOverflow.
Thank you!

@lhazlewood
Copy link
Contributor

Please let us know if you find a solution!

@t0in4
Copy link
Author

t0in4 commented Jun 9, 2022

@lhazlewood
Copy link
Contributor

lhazlewood commented Jun 9, 2022

Your StackOverflow post indicates that, after registering BouncyCastle, a JWT is created on Android without any exceptions/problems, but yandex cannot validate it.

So I'm curious - have you tried the following tests?

  1. Generate a token via android, and see if it verifies on the JVM in IntelliJ.
  2. Generate a token via android, and see if it verifies with another 3rd party testing tool, like https://jwt.io

If both of those work successfully, the problem is with yandex, not with Android.

@t0in4
Copy link
Author

t0in4 commented Jun 10, 2022

Thank you!
Just now check both token output on https://jwt.io

They are not same

Android Studio
android Studio

IntelliJ Idea
intelliJ Idea

The order of representation of the payload data is not same. In token from IntelliJ Idea the "aud" is first and "iss" is second,

in token from Android Studio the "iss" is first and "aud" is second.

@bdemers
Copy link
Member

bdemers commented Jun 10, 2022

The order doesn't matter for JWT claims (headers or payloads). It's basically a hashmap of key/value pairs, so the order could change. As long as the content is the same you would be all set.

@t0in4
Copy link
Author

t0in4 commented Jun 10, 2022

Thank you!
I ask yandex service support maybe they will answer. I will write their response

@t0in4
Copy link
Author

t0in4 commented Jun 13, 2022

Yandex support says that i have to add parameter to header - "type": "JWT",
i try to add this to Jwts.builder().setHeaderParams(params) but the error is same
{ "code": 16, "message": "JWT signature validation fails", "details": [{ "@type": "type.googleapis.com/google.rpc.RequestInfo", "requestId": "23b32b5a-1a9b-4bea-bba2-66beede0ca61" }] }
also i try to add this parameter directly to POST request (undo to the setHeaderParam("kid": keyId)) but the error is same.

@bdemers
Copy link
Member

bdemers commented Jun 13, 2022

Hey @t0in4!
Per spec this header IS optional: https://datatracker.ietf.org/doc/html/rfc7519#section-5.1
But in your case to work with Yandex, try using typ instead of "type" (the claims in the JWT core specs are all 3 characters)

Fun Fact: There is an official registry of additional JWT claims names: https://www.iana.org/assignments/jwt/jwt.xhtml

@lhazlewood
Copy link
Contributor

If Yandex requires the typ header, they are wrong for doing so - as @bdemers states, it is definitely optional per the JWT specification.

@t0in4
Copy link
Author

t0in4 commented Jun 14, 2022

changed to "typ" - error is same

{
"code": 16,
"message": "JWT signature validation fails",
"details": [{
"@type": "type.googleapis.com/google.rpc.RequestInfo",
"requestId": "c272bc56-5aec-4809-b757-4ca03de01ad5"
}]
}

@bdemers
Copy link
Member

bdemers commented Jun 15, 2022

Is the receiving end configured with the correct key?

@t0in4
Copy link
Author

t0in4 commented Jun 16, 2022

Hello!
Yes, i think the receiving end is properly cofigured, becouse token from IntelliJ is return iam_token.
Code is same as in Android Studio

@bdemers
Copy link
Member

bdemers commented Jun 16, 2022

Sorry, @t0in4 I think I missed some part of the thread.
How did you get past the Android missing algorithm part?

@t0in4
Copy link
Author

t0in4 commented Jun 16, 2022

As you both told to me the solution is:

`val provider: Provider = BouncyCastleProvider()

Security.removeProvider("BC");

Security.addProvider(provider)

java.security.Signature.getInstance("RSASSA-PSS", "BC");`

Above code annihilate the error "no such algorithm: RSASSA-PSS for provider BC"
Before getting result of getJWT() function.
Thank you very much!

And the checking both tokens give a same output on site https://jwt.io

But when i making POST request to get a iam_token - the IntelliJ Idea's token return a iam_token, but the Android Studio's token return an error "JWT signature validation fails".

The orders of payload is not equal - data is equal but order of representation is not.

@bdemers
Copy link
Member

bdemers commented Jun 16, 2022

Ahh cool! I think I read one of your previous posts incorrectly! Thanks for clarifying!

Here is what I would recommend.
Write some example code in your IntelliJ app, to decode the token:
Something like:

Jwts.parserBuilder()
  ... // your settings
  .build()
  .parse(jwtTokenString);

Once you have that working, use the token string created by your Android app.
If this fails, it may help narrow down the actual cause.

@t0in4
Copy link
Author

t0in4 commented Jun 17, 2022

Thank you!
i decode the both tokens from IntelliJ and from Android Studio, here is output
`
// encoded token from IntelliJ Idea
encoded token eyJraWQiOiJhamU5MmRwYzR0NHR1N2JidTh1biIsImFsZyI6IlBTMjU2In0.eyJhdWQiOiJodHRwczovL2lhbS5hcGkuY2xvdWQueWFuZGV4Lm5ldC9pYW0vdjEvdG9rZW5zIiwiaXNzIjoiYWplaWpwMTltNTk5czhhb3M2dnIiLCJleHAiOjE2NTU0NTA5NzksImlhdCI6MTY1NTQ1MDYxOX0.b3L92h6uUv29BB7Rs6bPcRwl4kvmPeEmBe3V2gOumR97vS20edjpDPhf_e105EkQB_v7su6YJdOUx_gWMLRZQVCm7Nncv1WedQPLY6O318UNZwKQAuThDYf6E3JKRDvd4GoaBRxrfTNyo5q598ZpSQISD6Acf-i9Qhj9nucnV515hPANLwujUGNUNXtpWvOyL0YmrkrFVyPHidV4lnEzhz5JHyZ-r2H-9vlGRED67QVL-4PV-Ip5Nm0mWRJJeDroOSeFBg-Bk1HvBKGB46ZpzjSLeqYxBpmupOpBsLc_Vb5JBPQtiv1-_JPyrTpSyVgYh8AatdHuQ5FTWH3HyFfzAw

// decoded output of token from IntelliJ Idea
header={kid=aje92dpc4t4tu7bbu8un, alg=PS256},body={aud=https://iam.api.cloud.yandex.net/iam/v1/tokens, iss=ajeijp19m599s8aos6vr, exp=1655450979, iat=1655450619},signature=b3L92h6uUv29BB7Rs6bPcRwl4kvmPeEmBe3V2gOumR97vS20edjpDPhf_e105EkQB_v7su6YJdOUx_gWMLRZQVCm7Nncv1WedQPLY6O318UNZwKQAuThDYf6E3JKRDvd4GoaBRxrfTNyo5q598ZpSQISD6Acf-i9Qhj9nucnV515hPANLwujUGNUNXtpWvOyL0YmrkrFVyPHidV4lnEzhz5JHyZ-r2H-9vlGRED67QVL-4PV-Ip5Nm0mWRJJeDroOSeFBg-Bk1HvBKGB46ZpzjSLeqYxBpmupOpBsLc_Vb5JBPQtiv1-_JPyrTpSyVgYh8AatdHuQ5FTWH3HyFfzAw
decoded token kotlin.Unit

// encoded token from Android Studio
Android encoded token eyJraWQiOiJhamU5MmRwYzR0NHR1N2JidTh1biIsInR5cCI6IkpXVCIsImFsZyI6IlBTMjU2In0.eyJpc3MiOiJhamVpanAxOW01OTlzOGFvczZ2ciIsImF1ZCI6Imh0dHBzOlwvXC9pYW0uYXBpLmNsb3VkLnlhbmRleC5uZXRcL2lhbVwvdjFcL3Rva2VucyIsImlhdCI6MTY1NTQ1MDQ5NCwiZXhwIjoxNjU1NDUwODU0fQ.Swv4MSF7rdfmg3alTmHSnDtt7v-xZjSMLepIvAih-WFtMTKp6uZZWSCF19D1nOuEmlvtBPWT-6UEzw4sH-OcxW5wYu-GHDpEA2jOnp8BIjKFV_ZnmOdy8zV2ue-waZltmvytNQHBUBwfkVGo09-UGpx4KCm6mLCAiMTEuS6Xbsp4wDUVBC8-lhvYw5e9e51JuFclytjQoxfGetI7CuZw7supF-1Dds_zwEPzUpUbawboQiEwkKfN1dmSq-CdmrWX38hXUhIgoaUBmzJucAGZ-fcMa8N1GgqqnCfDuBBQZdq6BpCkAZBVczZTV6OBiEIu67hjRKFp7XFAolDHitkIoA

// error when decoding token from Android Studio
Exception in thread "main" io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:399)
at io.jsonwebtoken.impl.ImmutableJwtParser.parse(ImmutableJwtParser.java:148)
at MainKt.decodeJWT(Main.kt:86)
at MainKt.main(Main.kt:22)

Process finished with exit code 1`

Screenshot from 2022-06-17 10-43-56

Whole code of decoder on https://github.com/t0in4/decode_android_JJWT/tree/master

@lhazlewood
Copy link
Contributor

I issued a PR to your sample project here:

https://github.com/t0in4/small_project/pull/1/files

This PR enables the BouncyCastle provider correctly, whereby the JWT PS* algorithms will work correctly. Note the build.gradle and proguard exclusions modifications.

However, the most important change was the following added to the main application class (how Kotlin does a static { ... } initialization block in a class):

    companion object {
        init {
            Security.removeProvider("BC") // remove the legacy Android-specific 'BC' provider
            Security.addProvider(BouncyCastleProvider()) // add the real BC provider
        }
    }

This should be all that is necessary to resolve this. If so, please confirm. I'd like to close this issue ;)

@t0in4
Copy link
Author

t0in4 commented Jun 18, 2022

Cool! Code is amazing! Thank you!

Yes, JJWT error is solved. Thank you all one more time.

I'm very appreciated. Thank you sirs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants