Generate JWS (json web signature) with Ed25519 algo in Dart

380

The required 64 bytes key is produced by concatenating the private and public key:

The posted private key is hex encoded:

d069ce872b6565fae38cae0faa63459cc14aea9e88537c85bef8cdc4d97ea4c4

The corresponding public key was not posted, but can be calculated to (hex encoded):

5067025e39f7628f60c91c178287b28446b34a752579e709dcb1ad1ac8dc6401

Thus the required 64 bytes key is (hex encoded):

d069ce872b6565fae38cae0faa63459cc14aea9e88537c85bef8cdc4d97ea4c45067025e39f7628f60c91c178287b28446b34a752579e709dcb1ad1ac8dc6401

or Base58 encoded:

5AgHMMkzfDxdAHHHmpqjQYLqaKnrXTddWGpMQW8Dsj4391Fm7G79ZutmKwZousSvUWbYsf1W8Q12RAMFjXjDcDs6

A possible JWT generated with:

generateJwt('the subject', '5AgHMMkzfDxdAHHHmpqjQYLqaKnrXTddWGpMQW8Dsj4391Fm7G79ZutmKwZousSvUWbYsf1W8Q12RAMFjXjDcDs6');

is:

eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoidGhlIHN1YmplY3QiLCJpYXQiOjE2MjgwMTkyNDIsImlzcyI6InRoZSBzdWJqZWN0In0.17gFglAs7g8ztBTDsfIx7B6l1GFkbI96xezX6g53lEvoy9HfNqT1wc8MApa8uA1muLDU4MWiwgmpwO51beZDBw

A simple test is to verify the message:

eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0IjoidGhlIHN1YmplY3QiLCJpYXQiOjE2MjgwMTkyNDIsImlzcyI6InRoZSBzdWJqZWN0In0

with its signature:

17gFglAs7g8ztBTDsfIx7B6l1GFkbI96xezX6g53lEvoy9HfNqT1wc8MApa8uA1muLDU4MWiwgmpwO51beZDBw

using Ed25515 and a second, independent program. I was able to verify this successfully using C#/BouncyCastle.

Share:
380
JonasLevin
Author by

JonasLevin

Updated on December 31, 2022

Comments

  • JonasLevin
    JonasLevin over 1 year

    I want to sign a json web signature with a privateKey generated through Ed25519. Then send this signature to my backend and verify it with the public key in Node.js. Currently im stuck at creating a json web signature with Dart.
    The privateKey is base58 encoded so I first decode it to a list of integers as seen below:

    String generateJwt(String subject, String secret) {
      var decodedRaw = Base58Decode(secret);
    
      print(decodedRaw);
      /* [208, 105, 206, 135, 43, 101, 101, 250, 227, 
      140, 174, 15, 170, 99, 69, 156, 193, 74, 234, 
      158, 136, 83, 124, 133, 190, 248, 205, 196, 
      217, 126, 164, 196] */
    
      final payload = {"id": subject};
    }
    

    Now I want to use the payload as the payload of a JWS and protect the header through my Ed25519 decoded privateKey. This is the format of a jwt created with jose in Node.js:

    {
      payload: { subject: 'uuid', exp: 1627901626 },
      protectedHeader: { alg: 'EdDSA' }
    }
    

    My goal is to create a JWS in the same format on the local device with Dart.

    EDIT:
    I now found the package dart_jsonwebtoken which makes it possible to sign json web tokens with the Ed25519 curve algorithm.

    import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
    import 'package:fast_base58/fast_base58.dart';
    
    generateJwt(String subject, String secret) {
      final decodedRaw = Base58Decode(secret);
    
      // Create a json web token
      final jwt = JWT(
        {
          'subject': subject,
        },
        issuer: subject,
      );
    
      final key = EdDSAPrivateKey(decodedRaw);
    
      final token = jwt.sign(key, algorithm: JWTAlgorithm.EdDSA);
    
      print('Signed token: $token\n');
    }
    

    But I now get the error : ed25519: bad privateKey length 32. It obviously indicates that my privateKey has the wrong size. The Repo states that the PrivateKeySize is 64 bytes but is there a way to ust just a privateKey of size 32, because my keys, generated through Ed25519 always have a size of 32

    /// PublicKeySize is the size, in bytes, of public keys as used in this package.
    const PublicKeySize = 32;
    
    /// PrivateKeySize is the size, in bytes, of private keys as used in this package.
    const PrivateKeySize = 64;