Reputation: 560
I am trying to set up a JWT auth system for a website. On the server side(where I use Python/Flask) I generate the token using the library PyJWT. On the frontend/app I am using Flutter(dart) with the library dart_jsonwebtoken for verification.
I am encoding the JWT with a RSA key of 4096 bytes. I generate the key using something like:
def generate_auth_token():
payload = {
"sub": "1",
"aud": "audience",
"iss": "issuer"
}
private_key = rsa.generate_private_key(public_exponent=65537, key_size=4096)
priv_key = private_key.private_bytes(encoding=Encoding.PEM, format=PrivateFormat.PKCS8, encryption_algorithm=NoEncryption())
pb_key = private_key.public_key().public_bytes(encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo)
# print(f'Private Key: {priv_key}')
# print(f'Public Key: {pb_key}')
token = jwt.encode(payload, priv_key, algorithm="RS512")
# I am decoding it here just to as a check that it decodes on server.
# but I doubt that is important for the question.
return token
and then sending it back as:
@blueprint.route('/token', methods=["GET", "POST"])
def token():
# For now I am ignoring username/password, just trying to get the token to be verified
token = generate_auth_token()
return jsonify(key=token)
This seems to generate the token correctly, and I am able to decode it on the server or using online tool checkers as jwt.io or token.dev.
On the application, I receive the token and try to decode it as:
final Response resp = await post(loginUri, headers:_headers, body:body); // Send the request to get the token.
final Map<String, dynamic> jsonData = json.decode(resp.body);
_token = JWT.verify(jsonData["key"], key); // where key is the public key generated on the server.
but for some reason it fails to decode with invalid signature.
I have tried to verify a token generated in the server directly on Flutter (just to check if the error was on the parsing of the JSON or similar) with:
void test_verify() {
print("Testing JWT verification...");
final jwt = JWT(
{},
audience: Audience.one("audience"),
subject: "1",
issuer: 'issuer',
);
final privKey = RSAPrivateKey(server_privateKey);
final pubKey = RSAPublicKey(server_publicKey);
final app_token = jwt.sign(privKey, algorithm: JWTAlgorithm.RS512);
print('Signed token: $token\n');
final app_token_decoded = JWT.verify(app_token , pubKey);
print('Payload: ${app_token_decoded.payload}');
final JWT? server_JWT= JWT.tryVerify(server_token, privKey);
if (server_JWT== null) {
print("Not decoded...");
} else {
print("At least decoded!!");
}
where the server_privateKey,server_publicKey and server_token are the ones generated in the server. For some reason, the pub key is able to sign and verify the app_token generated in the app, but it is unable to verify the token that comes from the server. If the Key Pair is able to sign and verify a token in the app, I assume the key pair is correct, and I am thinking that the issue is probably on the JSON parse on the app or the String encode on the server, but I can't see where the problem is exactly.
These are the token used in case that helps. (This are only for testing, so no security breach)
const String server_token = '''eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwiYXVkIjoiYXVkaWVuY2UiLCJpc3MiOiJhdWRpZW5jZSJ9.mwCNH8ocjhRmBjSrI-T_IjeXfzrGhEMfI0l-u2SN7fs0mSc1TwD9AVVebtAJWPDz4AvvsCK8fwqAJdVrG7MJdKHFnzB1zfdD30e6BATy2XQcrx8phtZQfsbcsY_pvbom9ANK8rZe_Gb18LMYxnuPLnQkQnW1D2tinKkb0PMMnLFh3yW4bD-Wl5WmWV0SNUhQGsyst5oPJPEtgspF-iJ3lD2YZBy-3l7SAGxJ5H4zbefCemNnO_jCEKlmwGAP36Xb2T98UYVcnnKW82uqVm7KVBQazyIc2c3_iKqf9MuRk51kIPSQjRTOmHSCh34nl75YP0HTkfKk47NuyteIFCm4ZALxslsYyl3oepCFQMIQRCV-H_8XAnQTcaoFrSUWe-YJLqPrg4MKOtzISyFnsillyvgc7G0BFlbad8TCJwMLBC8QCKZJ0UdaDmXQQOJS42OeXWxUErCgrdjAWgZAGylSiQ4B6QEoj9AWK3I6V6Meeg9rL6C1zU3EdSvtj54-fQqfbRMvLY9bn44rbZg0v0NKKfm1OSc3pqmqxugdOpzMkdd00zdyWQE8gRe7jx09SbJunnNPTBcXD80H5SdaEiAOJJKKc3_8rAM-v9aPXDbxrDzQ-mNrx-FpF3Ova2QUWMcImSmX8LmboUKhM77dWOapinnmlhUE-o5FcwTw4PDF70A''';
const String server_publicKey = '''
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzxXUEszf1aeDjQ50+KEp
9SVB+Wp047MsdvWtOEspD5foFFeFT17ZTbB7im+vkDIPN9ksWhquK+1v8Ur2Cgpa
qEpzAo/jnRv3fwy3fZ/UchUeuRvClHYHIDLlof/pOUofYDAfM5iJVMA3Iv4Qb7Dj
i1xd03ZSVRR31DTVdYOszAZtD8fN+TsGjtIAszc9Gh13Qxr8okSGpWRt7JsF6bzI
hfa5bE0xmqTAvImva779otjx1a1utku3Pco1ddthXrAeOwvdIXNvdBaWFfDZRCcs
7wHizlj6LRBLBeZGY1/LntT9VFaf/Oi/ejnLJhMMkYrY13j/rNP94IbzkXvBDlLT
BTwcPDrT41eZzKEKVeGVXLGSS2bCphMBo5k7Weoku7Z2ZnUGqGVRNsDn/MsgeOxC
NSn0fMne//zrQcZhndVbFOYZRs0V4TnxRfbUM8iYT6t/ECqATCQgk1VUvDQYsd4/
ZiIAOyPk3RRnwJJK7wsVugEoVrhbqlqnwex5RQxd+RKnoQzUujDWJWq0cGp/6JlX
gJ3zHGfl7UBWMCQvXJW+bSptowWupEluuu+b0VIdjP7MYtvw5TKqAjB50ij7azhl
vnWqNQRHFAL2QjNK/LwSSiysiK4qK7gSCle+JhE/Ix5R2lVbWd2GNVcRd+FGc7bz
5eUk4r1B/fDR8MRz2Qvn0oUCAwEAAQ==
-----END PUBLIC KEY-----
''';
const String server_privateKey = '''
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDPFdQSzN/Vp4ON
DnT4oSn1JUH5anTjsyx29a04SykPl+gUV4VPXtlNsHuKb6+QMg832SxaGq4r7W/x
SvYKClqoSnMCj+OdG/d/DLd9n9RyFR65G8KUdgcgMuWh/+k5Sh9gMB8zmIlUwDci
/hBvsOOLXF3TdlJVFHfUNNV1g6zMBm0Px835OwaO0gCzNz0aHXdDGvyiRIalZG3s
mwXpvMiF9rlsTTGapMC8ia9rvv2i2PHVrW62S7c9yjV122FesB47C90hc290FpYV
8NlEJyzvAeLOWPotEEsF5kZjX8ue1P1UVp/86L96OcsmEwyRitjXeP+s0/3ghvOR
e8EOUtMFPBw8OtPjV5nMoQpV4ZVcsZJLZsKmEwGjmTtZ6iS7tnZmdQaoZVE2wOf8
yyB47EI1KfR8yd7//OtBxmGd1VsU5hlGzRXhOfFF9tQzyJhPq38QKoBMJCCTVVS8
NBix3j9mIgA7I+TdFGfAkkrvCxW6AShWuFuqWqfB7HlFDF35EqehDNS6MNYlarRw
an/omVeAnfMcZ+XtQFYwJC9clb5tKm2jBa6kSW6675vRUh2M/sxi2/DlMqoCMHnS
KPtrOGW+dao1BEcUAvZCM0r8vBJKLKyIrioruBIKV74mET8jHlHaVVtZ3YY1VxF3
4UZztvPl5STivUH98NHwxHPZC+fShQIDAQABAoICAAONn9RswIB1fdvbPiWP+lzS
9VVWvsezaNVntL+tBnjWhexnbgmlGnxrRUtkTDJgsYMnTkwDfi6RxeRxgVQ9xj1x
/ZQzLNgixTXgXXuh1O7aLutFLysF9WxXgzoq3nEVtQEdAkQL33tdSvTmQBjyg4z+
GjwJITOFhOLWvzzjdAESMSfeqUmX+i5UKx/oGDvM+qFjoqcUHu1SklJHfKv8icJG
r/rMPkglgIsbn69tGQQEze15Ktek5/F++Tja+Uo7ImGn+/TZerWWt5+LwOaa93no
YeBhhXVlfKwOvfFxkNhaVjhuvhMEWVi7CiHOnN4YcE0OLfDkuEv0dNRvt6nLwQQj
kMOMIkoz6boE/zKU7mKIPgZWqfqbUawGXR15xKF7ojZlxgzkEkKpqKBdYeEm8Nrz
PON39NCSewq8KbnTXjCgAyBTypfEkmJzu8UoME12LlbQxTdAekklOhFxNBZzDNSm
XnkzbMI3rTwJJU5OOOMn5FIfKVTJqDmuaffLpQJrS6kgOIivAggiBTd2HPgXGCa7
1HeGlfgTeFGJqCTUI6tC+hQ6beXPP9x0UAAw3LeUSQykNWevQJOaGQRO3SRFQK7F
m9VL1RSoTvTWd0T01fIGV7TWH7lpwF46wCaXJIQd+EkRCbhHPTj1TSXarRNRC3d2
XTDkFjtHJZc5pn/5ASgHAoIBAQDy3Gno9eAsOFBnrq7GSySPqFmVAS1VOPo60BCK
FxrZ1NwcrsP1026vZw3caEzrRzrG41s9Hr6z8JAkLb9OX3Lijw25SZeA5kvvqli9
YeJ3AE2+zn8R8FG4kBbM0OulGI0DTZGRxkEe2aJql4VzHb/LUwEJYQ884ZAgr86n
ZzpyZrCjyrsE463A7QRmWNYRWulhH0Z7MD/j8ygl9xbx7e4H7aqP59QQ2Wsm3Fxp
CpF146fYXQCyWqJ/CgBrF7weWOTv/tsCP58GtMDaSbjgHam0Rl0oyix7S5NnN9FX
h20wo8J5siC4w/0rVO+4ODorXuPuiiSl0fdd+q7l6PW1C1ADAoIBAQDaSe004MgL
3c0a6ppxPOjhBMoqA6h7Pp+SSv71QgvM4NJmz7dU71Q1op8F4oIZVoVZp+gaD7Nj
P2Wp1ohWfQ6shJFtSQfHWb2O6P+XknrBHlj9nYjYA35k1G4FYZQbfhvkRp+TuO2W
vz5ILY+4QIOJnciKVj/UH9Bw6v6B67BT+HLFUUZrL8nzAUA7JcYjTrM+YBrkg+W4
RTTY17+2mL5Gu8wtzvRijAuPuucci6dqQo7KMpf5BcKR/j1zV99GdDNEMbDSP83p
G1boSlxO8dAZTL7agTn6do+6JFxmJLL424Cez70xnwBjt0KmvPP3/vrxyexbQFzE
9IpStcX4d+DXAoIBAQCtDns50dtIJ2jEOSm5i1omNCSBlTEkhVFqD1F51TUA/DlN
BwwEZAF/Y8PwxzHohf1QNDqTtxDVUBqmbSLhSgqnfqCc49/drj12LsDFUrb5bXH5
AVRzB/hzt9lHYahJINF7BQ8x/T/yJ8sggZBKk2xUCnW2pT8idukpIZ30lA6F7r74
OEJEHal2zG5SMAN6onmjB5JFvgAJAwAc7ZGgG5d+dtEPcnce+o7sRiJjh3BXvT2h
Y8RXU1ZviET8CxG13kpk6gpN89/x+2NhKR9gNEL1fx5rLoW75gLHjnLSGGKqQkcW
SOQgRShmdEPN1eM9fISXOkEbGB9ZDIUMt5A+zizZAoIBABqW7LUHOHbxkp1XvG5U
vA1E1xddELXKgAeC6SGY5PUU4awyWyOWb4yE/Zfq6mwJtP6hzEz4YqKRQ2H3xu26
GAJ9t3U3cyIeVU/GI/QjnJ5PgwmJmfSuIERJ+AjhxPfAWcdpruCAozg8nWqPWjVY
bm1h8d6f+PBu26YVieDrg7QGzHwqlUhTLudR3LAXvtXoLT9I153ET0Qt8e0EAs9M
NclJ8OoXjn8+jd35J1O70y3HY7tPhGGKCRRdgsC9EG51kxUYdHB34y4k7WYoQKxB
GlcqmQjmutg+fu1upm6uw7o6iqVNqr8TnimHVjAXTiSEQ68WKJtI8MPxAbRnffDx
MUsCggEBAKvh+bUJbLZIjyk8VA4KsJJrPq6vevBEVGARoJPabGDRcgNRN/kYl5Q+
BbP31OlWrQvxwnMVUZt4aDHh6AuH69JEKpEjrpfpF8xbr9a9R7orcOZ8090mWVSZ
SoYnJUiodOM6LUwuZYZlNrKJXq5iFI4izHBi5Dh3G8wHL8qPwjrjrr4jE1fgZF5K
xEKfmkmDmZH8NlAEP6qDFi4JyJv/aYCpvfcGjXFx01i0P5aIgUnQu1zRxKSgCiXG
ixMF0IuuckGvJE7zRW7pA4dsaPvjEpH1TywEwSO4vfFuMcjtrfdPUW1UWxg+J7C1
3ERMB0FAXB6DTIXOV8YRcm3wdyBDajA=
-----END PRIVATE KEY-----
''';
Upvotes: 0
Views: 164