Support EdDSA for JWT (#7)

This commit is contained in:
Crossle Song
2021-03-16 23:47:08 +08:00
committed by GitHub
parent 78cb96c7dd
commit 714d8e7d52
7 changed files with 136 additions and 5 deletions

View File

@ -3,6 +3,7 @@ import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:pointycastle/pointycastle.dart' as pc;
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
import 'errors.dart';
import 'keys.dart';
@ -36,6 +37,9 @@ abstract class JWTAlgorithm {
/// ECDSA using P-512 curve and SHA-512 hash algorithm
static const ES512 = _ECDSAAlgorithm('ES512');
/// EdDSA using Ed25519 curve algorithm
static const Ed25519 = _EdDSAAlgorithm('EdDSA');
/// Return the `JWTAlgorithm` from his string name
static JWTAlgorithm fromName(String name) {
switch (name) {
@ -57,6 +61,8 @@ abstract class JWTAlgorithm {
return JWTAlgorithm.ES384;
case 'ES512':
return JWTAlgorithm.ES512;
case 'EdDSA':
return JWTAlgorithm.Ed25519;
default:
throw JWTInvalidError('unknown algorithm');
}
@ -78,6 +84,35 @@ abstract class JWTAlgorithm {
bool verify(Key key, Uint8List body, Uint8List signature);
}
class _EdDSAAlgorithm extends JWTAlgorithm {
final String _name;
const _EdDSAAlgorithm(this._name);
@override
String get name => _name;
@override
Uint8List sign(Key key, Uint8List body) {
assert(key is EdDSAPrivateKey, 'key must be a EdDSAPrivateKey');
final privateKey = key as EdDSAPrivateKey;
return ed.sign(privateKey.key, body);
}
@override
bool verify(Key key, Uint8List body, Uint8List signature) {
assert(key is EdDSAPublicKey, 'key must be a EdDSAPublicKey');
final publicKey = key as EdDSAPublicKey;
try {
return ed.verify(publicKey.key, body, signature);
} catch (ex) {
return false;
}
}
}
class _HMACAlgorithm extends JWTAlgorithm {
final String _name;

View File

@ -13,6 +13,7 @@ class JWT {
/// - SecretKey with HMAC algorithm
/// - RSAPublicKey with RSA algorithm
/// - ECPublicKey with ECDSA algorithm
/// - EdDSAPublicKey with EdDSA algorithm
static JWT verify(
String token,
Key key, {
@ -166,6 +167,7 @@ class JWT {
/// - SecretKey with HMAC algorithm
/// - RSAPrivateKey with RSA algorithm
/// - ECPrivateKey with ECDSA algorithm
/// - EdDSAPrivateKey with EdDSA algorithm
String sign(
Key key, {
JWTAlgorithm algorithm = JWTAlgorithm.HS256,
@ -210,7 +212,7 @@ class JWT {
);
}
final body = '${b64Header}.${b64Payload}';
final body = '$b64Header.$b64Payload';
final signature = base64Unpadded(
base64Url.encode(
algorithm.sign(

View File

@ -1,4 +1,5 @@
import 'package:pointycastle/pointycastle.dart' as pc;
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
import 'errors.dart';
import 'parser.dart';
@ -12,6 +13,24 @@ class SecretKey extends Key {
SecretKey(this.key);
}
/// For EdDSA algorithm, in sign method
class EdDSAPrivateKey extends Key {
late ed.PrivateKey key;
EdDSAPrivateKey(List<int> bytes) {
key = ed.PrivateKey(bytes);
}
}
/// For EdDSA algorithm, in verify method
class EdDSAPublicKey extends Key {
late ed.PublicKey key;
EdDSAPublicKey(List<int> bytes) {
key = ed.PublicKey(bytes);
}
}
/// For RSA algorithm, in sign method
class RSAPrivateKey extends Key {
late pc.RSAPrivateKey key;