jonasroussel / dart_jsonwebtoken

A dart implementation of the famous javascript library 'jsonwebtoken'
MIT License
87 stars 29 forks source link

JWTUndefinedError: Bad state: Too few elements #24

Closed rtessler closed 2 years ago

rtessler commented 2 years ago

I am intermittently getting JWTUndefinedError: Bad state: Too few elements while calling sign dart_jsonwebtoken: ^2.4.1 I am generating a token for apple music api It happens infrequently. my code looks like this:

var jwt = JWT({ "iss": "issuer code", "iat": (DateTime.now() .toUtc() .millisecondsSinceEpoch / 1000) .ceil(), "exp": (DateTime.now() .toUtc() .add(Duration(days: 50)) .millisecondsSinceEpoch / 1000) .ceil(), }, header: { "alg": "ES256", "kid": "VMK43GDD74" }, issuer: "issuer code");

jonasroussel commented 2 years ago

I can't reproduce this bug with this code :

import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';

void main(List<String> arguments) {
  var jwt = JWT({
    "iss": "issuer code",
    "iat": (DateTime.now().toUtc().millisecondsSinceEpoch / 1000).ceil(),
    "exp": (DateTime.now().toUtc().add(Duration(days: 50)).millisecondsSinceEpoch / 1000).ceil(),
  }, header: {
    "alg": "ES256",
    "kid": "VMK43GDD74"
  }, issuer: "issuer code");

  var privKey = ECPrivateKey('''-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r
1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G
-----END PRIVATE KEY-----''');

  var token = jwt.sign(privKey, algorithm: JWTAlgorithm.ES256);

  print(token);
}

Can you give me more info on your code ?

rtessler commented 2 years ago

sorry about that, here is some code that should make it happen eventually. timing related: calling the function 1000 times is what happens in my code of course, but im just trying to reproduce it

final appleKey = '''-----BEGIN PRIVATE KEY----- MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgdxD1N3x+tfDGJMdSj78D+qDfUzzt/B8weVBnkA5a0pCgCgYIKoZIzj0DAQehRANCAATfgQbUFgUANlhrg+ikfkdkIiPAD3jL9j6typO5XVbysSMLKIszsoUwNWGftp6tdTGXBDPAVAVIqdmcjthyZy+z -----END PRIVATE KEY-----''';

void getToken() { var jwt = JWT({ "iss": "8P7U6FARKW", "iat": (DateTime.now().toUtc().millisecondsSinceEpoch / 1000).ceil(), "exp": (DateTime.now() .toUtc() .add(const Duration(days: 50)) .millisecondsSinceEpoch / 1000) .ceil(), }, header: { "alg": "ES256", "kid": "VMK43GDD74" }, issuer: "8P7U6FARKW");

// sometimes sign or verify returns error: 'JWTUndefinedError: Bad state: Too few elements developerToken'

try {
  var token =
      jwt.sign(ECPrivateKey(appleKey), algorithm: JWTAlgorithm.ES256);

  jwt.sign(SecretKey('verify'));
} catch (error) {
  print('getToken ${error.toString()}');
}

}

void developerToken() async { print('start');

for (var i = 0; i < 1000; i++) {
  await Future.delayed(const Duration(milliseconds: 100), () => getToken());
}

print('end');

}

jonasroussel commented 2 years ago

Sorry, I can't reproduce this bug... The only hint that I have is this: https://gitcoin.co/issue/dart-bitcoin/bip32-dart/5 But because it only happens randomly for you I can't change the fundamental decodeBigInt function

But just to be sure, in your code if you try to verify a token like this:

jwt.sign(SecretKey('verify'));

It will not works, you need to do that instead:

JWT.verify(token, ECPublicKey(publicKey));
rtessler commented 2 years ago

i understand, I cant reproduce it reliably but it still occurs. Since it only happens occasionally I store the previous token and use that.