This commit is contained in:
Jonas Roussel
2023-08-26 18:56:21 +02:00
parent 1206d1ad0d
commit 8b162293d5
11 changed files with 441 additions and 56 deletions

View File

@ -1,3 +1,9 @@
## 2.11.0
- Removing `basic_utils` package that was incompatible with flutter web
- Moving utils to `helpers.dart` and key parsing functions into `key_parser.dart`
- Adding some new examples in `example/example.dart`
## 2.10.0
- New ECDSA algorithm (ES256K)

View File

@ -22,6 +22,10 @@ void main() {
print('----- RSA-PSS SHA-256 -----');
ps256();
print('---------------------------\n');
print('----- RSA Certificate -----');
rsaCert();
print('---------------------------\n');
}
// HMAC SHA-256 algorithm
@ -232,3 +236,46 @@ void ps256() {
}
}
}
// RSA Certificate
void rsaCert() {
String token;
/* Sign */ {
// Create a json web token
final jwt = JWT(
{
'id': 123,
'server': {
'id': '3e4fc296',
'loc': 'euw-2',
}
},
issuer: 'https://github.com/jonasroussel/dart_jsonwebtoken',
);
// Sign it
final pem = File('./example/rsa_cert_private.pem').readAsStringSync();
final key = RSAPrivateKey(pem);
token = jwt.sign(key, algorithm: JWTAlgorithm.RS256);
print('Signed token: $token\n');
}
/* Verify */ {
try {
// Verify a token
final pem = File('./example/rsa_certificate.pem').readAsStringSync();
final key = RSAPublicKey.cert(pem);
final jwt = JWT.verify(token, key);
print('Payload: ${jwt.payload}');
} on JWTExpiredException {
print('jwt expired');
} on JWTException catch (ex) {
print(ex.message); // ex: invalid signature
}
}
}

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHr1vavB+pZ0e/
0vp7fzElDST0TffrAGvLvo6QUmn8AdzNGEiytW2GeYGBMEGni/I89/S6e0SWsVqa
XJjqDlXqefZUzPzbyfd9URwah0vcHFKk+bM7ZsvOxvlRhKYwx3waNzOlcfetlB5h
pFCiHotoUJL9sbVjoByMbs3BQP87gDSRAfkgdNhyt73Qe4mxlXBo7Ay+3dRLJZmV
IegJDQ2Ktxlsg25nYn84fpOQHlzoU4BMSKRZvVflKUblJllpwXETDvD52FlvITeo
2qdeTaerBUlOWVAYD31hJzfPUIynt4LZ7k6of73lkBH93ZOcVfYeyCGtt4fGMNJi
JxxjHkVnAgMBAAECggEAEPikc+i9QCaZAIKr60caJC4D0Ae4ZG66uqxNbZKzk0mN
PJktxJKK5nz5NsOlMNpCElB4qkjDwZL9QlVQYcQqJS2MdBSgAQYfVLVKEC8jkWeO
1pqqUwgflklu8zC09zxdHdVHPG59QHFwS5gtijnSW2FNvOYXpon7IyxfrGcbyjCq
vsEo4DkrTs2ZALkONSfYuRVMtMyWOZcOET8MKFYy6LtFzQaEB9TUPXwauF5oMxab
+S1iJLb4yPBos84Y1ooGQGl72neTueNF35qNHndkybSH0zcFFC48kdkc/PjkTfSt
ubgHDNmMEZDWgNdAK7igoLcwyS0lZiQgfVDfylbmcQKBgQDzAat/eZtBrdL4Gajk
oz2sFJQsftwX49T7xl3cKHBNKzc1J9SZHIqix8/Tajqtz5nHf8bwLkn9Z830BEjc
OM80hYh2vM1J9j1z7mo304+w3Y1tc+29rP+R65pJprMNiBEaTtPihtWBluL68hzi
f2Gl3pjJUA96KvCWL9LUiDDsswKBgQDSXLGV/eWm8tAB0NVzl8Mi35pAq63D107L
M+tqfg5+DiQhSkaL1N554uyyJ33+Q4YDctJB/9QrVppl5WysIjMBJtyYZAs8Qylz
n/JJcJzoIvxuNAEdKevxtLb934slRyGBWAGpCOkoxNhKKzN0ZovgC51OPNgCbMK7
5oYND9eGfQKBgQDSijbZKjY+0GiBtlGjTl+nkOjUKFFujWHBhhtaHNs3sOKTNmA3
DAh9glrolBgk8UIOHAHzpFdMqzxAV9n8m2fC3JLgNTI0C5kwsXbryWusVDgthYyM
kq+W8KbreveVGLegsH1ZvXKMZXtg6pXmE3E58cM0YB4Yvc1WgjbLFvg0iwKBgQCY
2TdD1/b9BmLzXs0pr3TfKv+Gy/d3XENpTLFacHuRRi8kbTazNZntkGAR1rYqgN+o
M87om72LO+L19Oywai0LQjR5GgA76kT9OZOvnv6zgXBPlsPUb/h7aKap8rrE/Fkx
BUQ3kTzxHY5W3esGQdiSk33aMkV2BZa9NvPiG8erdQKBgDlpbRVv3ypjDQxdgccT
4K0zyWgG0597PXF+wBCV3+1FryarzlBCaSN53daE/s+XzJh8pZEN5zV8SkjKdI+W
ccDgCZ/FL15OB/AuE6I6/T4g5NWXDqqWt5qMP+SU7oK+IpzpRZyq56SSLCXzvMzk
+PD5J7pSXLRdv9DJURCvZ2ny
-----END PRIVATE KEY-----

View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx69b2rwfqWdHv9L6e38x
JQ0k9E336wBry76OkFJp/AHczRhIsrVthnmBgTBBp4vyPPf0untElrFamlyY6g5V
6nn2VMz828n3fVEcGodL3BxSpPmzO2bLzsb5UYSmMMd8GjczpXH3rZQeYaRQoh6L
aFCS/bG1Y6AcjG7NwUD/O4A0kQH5IHTYcre90HuJsZVwaOwMvt3USyWZlSHoCQ0N
ircZbINuZ2J/OH6TkB5c6FOATEikWb1X5SlG5SZZacFxEw7w+dhZbyE3qNqnXk2n
qwVJTllQGA99YSc3z1CMp7eC2e5OqH+95ZAR/d2TnFX2HsghrbeHxjDSYiccYx5F
ZwIDAQAB
-----END PUBLIC KEY-----

View File

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDMjCCAhoCCQD3O5GD6JcncDANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJG
UjEWMBQGA1UECAwNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBwwFUGFyaXMxJDAiBgkq
hkiG9w0BCQEWFWdvLmpyb3Vzc2VsQGdtYWlsLmNvbTAeFw0yMzA4MjMxODU3MTJa
Fw0yNDA4MjIxODU3MTJaMFsxCzAJBgNVBAYTAkZSMRYwFAYDVQQIDA1JbGUtZGUt
RnJhbmNlMQ4wDAYDVQQHDAVQYXJpczEkMCIGCSqGSIb3DQEJARYVZ28uanJvdXNz
ZWxAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx69b
2rwfqWdHv9L6e38xJQ0k9E336wBry76OkFJp/AHczRhIsrVthnmBgTBBp4vyPPf0
untElrFamlyY6g5V6nn2VMz828n3fVEcGodL3BxSpPmzO2bLzsb5UYSmMMd8Gjcz
pXH3rZQeYaRQoh6LaFCS/bG1Y6AcjG7NwUD/O4A0kQH5IHTYcre90HuJsZVwaOwM
vt3USyWZlSHoCQ0NircZbINuZ2J/OH6TkB5c6FOATEikWb1X5SlG5SZZacFxEw7w
+dhZbyE3qNqnXk2nqwVJTllQGA99YSc3z1CMp7eC2e5OqH+95ZAR/d2TnFX2Hsgh
rbeHxjDSYiccYx5FZwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAAN08vxGGcZYKq
/5lPRUYr7+KzMr5wHQdEUluPVtMiYjpOeuP+vXtO+tgmabCJqlXGg/O0H/GhczGX
cGYEPye5ftjiRPYLjvAgHotJH2gnJ5w5y5bRYw3+r/JQkueEd617iHFNL2j0atxf
ULgfOfPXjLu+2Ch8c8z/J5u52H6xpXBNDRNCnfm2nqwMcsRXCitLMENxMv9IBmJD
y5hfMtlcFb7XOmlHr0eRuR1U4IVF4k9v2b1vCWYWJLhJHRWQFaLQPGm0Y/1KL1F3
eXA81iNBFKIzqgiB0SSRxIt+mx4ZHg7QCwAYqzLFK8m59KRCz+eD1Ho/cO9NC/rZ
vwLdy6e2
-----END CERTIFICATE-----

View File

@ -8,7 +8,7 @@ import 'package:pointycastle/pointycastle.dart' as pc;
import 'exceptions.dart';
import 'keys.dart';
import 'utils.dart';
import 'helpers.dart';
abstract class JWTAlgorithm {
/// HMAC using SHA-256 hash algorithm

View File

@ -1,5 +1,4 @@
import 'dart:convert';
import 'dart:typed_data';
final jsonBase64 = json.fuse(utf8.fuse(base64Url));
@ -90,18 +89,11 @@ BigInt bigIntFromBytes(Uint8List bytes) {
return bytes.fold(BigInt.zero, (a, b) => a * _b256 + BigInt.from(b));
}
Uint8List hexToUint8List(String hex) {
if (hex.length % 2 != 0) {
throw 'Odd number of hex digits';
List<String> chunkString(String s, int chunkSize) {
var chunked = <String>[];
for (var i = 0; i < s.length; i += chunkSize) {
var end = (i + chunkSize < s.length) ? i + chunkSize : s.length;
chunked.add(s.substring(i, end));
}
var l = hex.length ~/ 2;
var result = Uint8List(l);
for (var i = 0; i < l; ++i) {
var x = int.parse(hex.substring(2 * i, 2 * (i + 1)), radix: 16);
if (x.isNaN) {
throw 'Expected hex string';
}
result[i] = x;
}
return result;
return chunked;
}

View File

@ -7,7 +7,7 @@ import 'package:collection/collection.dart';
import 'algorithms.dart';
import 'exceptions.dart';
import 'keys.dart';
import 'utils.dart';
import 'helpers.dart';
class JWT {
/// Verify a token.

299
lib/src/key_parser.dart Normal file
View File

@ -0,0 +1,299 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/asn1/object_identifiers.dart';
import 'package:pointycastle/pointycastle.dart';
import 'package:pointycastle/ecc/ecc_fp.dart' as ecc_fp;
import 'helpers.dart';
abstract class KeyParser {
static const BEGIN_PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----';
static const END_PRIVATE_KEY = '-----END PRIVATE KEY-----';
static const BEGIN_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----';
static const END_PUBLIC_KEY = '-----END PUBLIC KEY-----';
static const BEGIN_EC_PRIVATE_KEY = '-----BEGIN EC PRIVATE KEY-----';
static const END_EC_PRIVATE_KEY = '-----END EC PRIVATE KEY-----';
static const BEGIN_EC_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----';
static const END_EC_PUBLIC_KEY = '-----END PUBLIC KEY-----';
static const BEGIN_RSA_PRIVATE_KEY = '-----BEGIN RSA PRIVATE KEY-----';
static const END_RSA_PRIVATE_KEY = '-----END RSA PRIVATE KEY-----';
static const BEGIN_RSA_PUBLIC_KEY = '-----BEGIN RSA PUBLIC KEY-----';
static const END_RSA_PUBLIC_KEY = '-----END RSA PUBLIC KEY-----';
//-------------//
// RSA Parsing //
//-------------//
static RSAPrivateKey rsaPrivateKeyFromPEM(String pem, {bool pkcs1 = false}) {
var bytes = bytesFromPEM(pem);
if (pkcs1) {
return rsaPrivateKeyPKCS1(bytes);
} else {
return rsaPrivateKey(bytes);
}
}
static RSAPrivateKey rsaPrivateKey(Uint8List bytes) {
var asn1Parser = ASN1Parser(bytes);
final topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
final privateKey = topLevelSeq.elements![2];
asn1Parser = ASN1Parser(privateKey.valueBytes);
final pkSeq = asn1Parser.nextObject() as ASN1Sequence;
final modulus = pkSeq.elements![1] as ASN1Integer;
final privateExponent = pkSeq.elements![3] as ASN1Integer;
final p = pkSeq.elements![4] as ASN1Integer;
final q = pkSeq.elements![5] as ASN1Integer;
return RSAPrivateKey(
modulus.integer!,
privateExponent.integer!,
p.integer,
q.integer,
);
}
static RSAPrivateKey rsaPrivateKeyPKCS1(Uint8List bytes) {
var asn1Parser = ASN1Parser(bytes);
var pkSeq = asn1Parser.nextObject() as ASN1Sequence;
var modulus = pkSeq.elements![1] as ASN1Integer;
var privateExponent = pkSeq.elements![3] as ASN1Integer;
var p = pkSeq.elements![4] as ASN1Integer;
var q = pkSeq.elements![5] as ASN1Integer;
return RSAPrivateKey(
modulus.integer!,
privateExponent.integer!,
p.integer,
q.integer,
);
}
static RSAPublicKey rsaPublicKeyFromPEM(String pem, {bool pkcs1 = false}) {
var bytes = bytesFromPEM(pem);
if (pkcs1) {
return rsaPublicKeyPKCS1(bytes);
} else {
return rsaPublicKey(bytes);
}
}
static RSAPublicKey rsaPublicKey(Uint8List bytes) {
final asn1Parser = ASN1Parser(bytes);
final topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
ASN1Sequence publicKeySeq;
if (topLevelSeq.elements![1].runtimeType == ASN1BitString) {
final publicKeyBitString = topLevelSeq.elements![1] as ASN1BitString;
final publicKeyAsn = ASN1Parser(
publicKeyBitString.stringValues as Uint8List?,
);
publicKeySeq = publicKeyAsn.nextObject() as ASN1Sequence;
} else {
publicKeySeq = topLevelSeq;
}
final modulus = publicKeySeq.elements![0] as ASN1Integer;
final exponent = publicKeySeq.elements![1] as ASN1Integer;
return RSAPublicKey(modulus.integer!, exponent.integer!);
}
static RSAPublicKey rsaPublicKeyPKCS1(Uint8List bytes) {
final publicKeyAsn = ASN1Parser(bytes);
final publicKeySeq = publicKeyAsn.nextObject() as ASN1Sequence;
final modulus = publicKeySeq.elements![0] as ASN1Integer;
final exponent = publicKeySeq.elements![1] as ASN1Integer;
return RSAPublicKey(modulus.integer!, exponent.integer!);
}
//---------------//
// ECDSA Parsing //
//---------------//
static ECPrivateKey ecPrivateKeyFromPEM(String pem, {bool pkcs1 = false}) {
final bytes = bytesFromPEM(pem);
if (pkcs1) {
return ecPrivateKeyPKCS1(bytes);
} else {
return ecPrivateKey(bytes);
}
}
static ECPrivateKey ecPrivateKey(Uint8List bytes) {
var asn1Parser = ASN1Parser(bytes);
var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
String? curveName;
// Parse the PKCS8 format
var innerSeq = topLevelSeq.elements!.elementAt(1) as ASN1Sequence;
var b2 = innerSeq.elements!.elementAt(1) as ASN1ObjectIdentifier;
var b2Data = b2.objectIdentifierAsString;
var b2Curvedata = ObjectIdentifiers.getIdentifierByIdentifier(b2Data);
if (b2Curvedata != null) {
curveName = b2Curvedata['readableName'];
}
var octetString = topLevelSeq.elements!.elementAt(2) as ASN1OctetString;
asn1Parser = ASN1Parser(octetString.valueBytes);
var octetStringSeq = asn1Parser.nextObject() as ASN1Sequence;
var octetStringKeyData =
octetStringSeq.elements!.elementAt(1) as ASN1OctetString;
final x = octetStringKeyData.valueBytes!;
return ECPrivateKey(
osp2i(x),
ECDomainParameters(curveName ?? 'prime256v1'),
);
}
static ECPrivateKey ecPrivateKeyPKCS1(Uint8List bytes) {
var asn1Parser = ASN1Parser(bytes);
var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
String? curveName;
// Parse the SEC1 format
var privateKeyAsOctetString =
topLevelSeq.elements!.elementAt(1) as ASN1OctetString;
var choice = topLevelSeq.elements!.elementAt(2);
var s = ASN1Sequence();
var parser = ASN1Parser(choice.valueBytes);
while (parser.hasNext()) {
s.add(parser.nextObject());
}
var curveNameOi = s.elements!.elementAt(0) as ASN1ObjectIdentifier;
var data = ObjectIdentifiers.getIdentifierByIdentifier(
curveNameOi.objectIdentifierAsString,
);
if (data != null) {
curveName = data['readableName'];
}
final x = privateKeyAsOctetString.valueBytes!;
return ECPrivateKey(
osp2i(x),
ECDomainParameters(curveName ?? 'prime256v1'),
);
}
static ECPublicKey ecPublicKeyFromPEM(String pem) {
final bytes = bytesFromPEM(pem);
return ecPublicKey(bytes);
}
static ECPublicKey ecPublicKey(Uint8List bytes) {
if (bytes.elementAt(0) == 0) {
bytes = bytes.sublist(1);
}
var asn1Parser = ASN1Parser(bytes);
var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
var algorithmIdentifierSequence = topLevelSeq.elements![0] as ASN1Sequence;
var curveNameOi = algorithmIdentifierSequence.elements!.elementAt(1)
as ASN1ObjectIdentifier;
String? curveName;
var data = ObjectIdentifiers.getIdentifierByIdentifier(
curveNameOi.objectIdentifierAsString);
if (data != null) {
curveName = data['readableName'];
}
var subjectPublicKey = topLevelSeq.elements![1] as ASN1BitString;
var compressed = false;
var pubBytes = subjectPublicKey.valueBytes!;
if (pubBytes.elementAt(0) == 0) {
pubBytes = pubBytes.sublist(1);
}
// Looks good so far!
var firstByte = pubBytes.elementAt(0);
if (firstByte != 4) {
compressed = true;
}
var x = pubBytes.sublist(1, (pubBytes.length / 2).round());
var y = pubBytes.sublist(1 + x.length, pubBytes.length);
var params = ECDomainParameters(curveName ?? 'prime256v1');
var bigX = decodeBigIntWithSign(1, x);
var bigY = decodeBigIntWithSign(1, y);
var pubKey = ECPublicKey(
ecc_fp.ECPoint(
params.curve as ecc_fp.ECCurve,
params.curve.fromBigInteger(bigX) as ecc_fp.ECFieldElement?,
params.curve.fromBigInteger(bigY) as ecc_fp.ECFieldElement?,
compressed,
),
params,
);
return pubKey;
}
//--------------//
// PEM to Bytes //
//--------------//
static Uint8List publicKeyBytesFromCertificate(String pem) {
var bytes = bytesFromPEM(pem);
var asn1Parser = ASN1Parser(bytes);
var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
var certSq = topLevelSeq.elements!.elementAt(0) as ASN1Sequence;
int element;
if (certSq.elements!.elementAt(0) is ASN1Integer) {
element = -1;
} else {
element = 0;
}
final pubKeySequence = certSq.elements!.elementAt(element + 6);
return pubKeySequence.encodedBytes ?? Uint8List(0);
}
static Uint8List bytesFromPEM(String pem) {
final lines = LineSplitter.split(pem)
.map((line) => line.trim())
.where((line) => line.isNotEmpty)
.toList();
final base64Data = lines.sublist(1, lines.length - 1).join('');
return Uint8List.fromList(base64Decode(base64Data));
}
//------------------//
// Helper Functions //
//------------------//
static BigInt osp2i(Iterable<int> bytes, {Endian endian = Endian.big}) {
var result = BigInt.from(0);
if (endian == Endian.little) {
bytes = bytes.toList().reversed;
}
for (var byte in bytes) {
result = result << 8;
result |= BigInt.from(byte);
}
return result;
}
}

View File

@ -1,11 +1,10 @@
import 'dart:typed_data';
import 'package:basic_utils/basic_utils.dart';
import 'package:dart_jsonwebtoken/src/utils.dart';
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
import 'package:pointycastle/pointycastle.dart' as pc;
import 'exceptions.dart';
import 'key_parser.dart';
abstract class JWTKey {}
@ -21,17 +20,15 @@ class RSAPrivateKey extends JWTKey {
late pc.RSAPrivateKey key;
RSAPrivateKey(String pem) {
if (pem.startsWith(CryptoUtils.BEGIN_RSA_PRIVATE_KEY)) {
key = CryptoUtils.rsaPrivateKeyFromPemPkcs1(pem);
} else {
key = CryptoUtils.rsaPrivateKeyFromPem(pem);
}
key = KeyParser.rsaPrivateKeyFromPEM(
pem,
pkcs1: pem.startsWith(KeyParser.BEGIN_RSA_PRIVATE_KEY),
);
}
RSAPrivateKey.raw(pc.RSAPrivateKey _key) : key = _key;
RSAPrivateKey.clone(RSAPrivateKey _key) : key = _key.key;
RSAPrivateKey.bytes(Uint8List bytes)
: key = CryptoUtils.rsaPrivateKeyFromDERBytes(bytes);
RSAPrivateKey.bytes(Uint8List bytes) : key = KeyParser.rsaPrivateKey(bytes);
}
/// For RSA algorithm, in verify method
@ -39,34 +36,25 @@ class RSAPublicKey extends JWTKey {
late pc.RSAPublicKey key;
RSAPublicKey(String pem) {
if (pem.startsWith(CryptoUtils.BEGIN_RSA_PUBLIC_KEY)) {
key = CryptoUtils.rsaPublicKeyFromPemPkcs1(pem);
} else {
key = CryptoUtils.rsaPublicKeyFromPem(pem);
}
key = KeyParser.rsaPublicKeyFromPEM(
pem,
pkcs1: pem.startsWith(KeyParser.BEGIN_RSA_PUBLIC_KEY),
);
}
RSAPublicKey.raw(pc.RSAPublicKey _key) : key = _key;
RSAPublicKey.clone(RSAPublicKey _key) : key = _key.key;
RSAPublicKey.bytes(Uint8List bytes) {
try {
key = CryptoUtils.rsaPublicKeyFromDERBytesPkcs1(bytes);
key = KeyParser.rsaPublicKey(bytes);
} catch (_) {
key = CryptoUtils.rsaPublicKeyFromDERBytes(bytes);
key = KeyParser.rsaPublicKeyPKCS1(bytes);
}
}
RSAPublicKey.cert(String pem) {
final x509 = X509Utils.x509CertificateFromPem(pem);
final bytes = x509.tbsCertificate?.subjectPublicKeyInfo.bytes;
if (bytes == null) {
throw JWTParseException('x509 Certificate parsing failed');
}
final bytes = KeyParser.publicKeyBytesFromCertificate(pem);
try {
key = CryptoUtils.rsaPublicKeyFromDERBytesPkcs1(hexToUint8List(bytes));
} catch (_) {
key = CryptoUtils.rsaPublicKeyFromDERBytes(hexToUint8List(bytes));
}
key = RSAPublicKey.bytes(bytes).key;
}
}
@ -76,7 +64,10 @@ class ECPrivateKey extends JWTKey {
late int size;
ECPrivateKey(String pem) {
final _key = CryptoUtils.ecPrivateKeyFromPem(pem);
final _key = KeyParser.ecPrivateKeyFromPEM(
pem,
pkcs1: pem.startsWith(KeyParser.BEGIN_EC_PRIVATE_KEY),
);
final _params = _key.parameters;
if (_params == null) {
@ -100,8 +91,7 @@ class ECPrivateKey extends JWTKey {
ECPrivateKey.clone(ECPrivateKey _key)
: key = _key.key,
size = _key.size;
ECPrivateKey.bytes(Uint8List bytes)
: key = CryptoUtils.ecPrivateKeyFromDerBytes(bytes);
ECPrivateKey.bytes(Uint8List bytes) : key = KeyParser.ecPrivateKey(bytes);
}
/// For ECDSA algorithm, in verify method
@ -109,21 +99,16 @@ class ECPublicKey extends JWTKey {
late pc.ECPublicKey key;
ECPublicKey(String pem) {
key = CryptoUtils.ecPublicKeyFromPem(pem);
key = KeyParser.ecPublicKeyFromPEM(pem);
}
ECPublicKey.raw(pc.ECPublicKey _key) : key = _key;
ECPublicKey.clone(ECPublicKey _key) : key = _key.key;
ECPublicKey.bytes(Uint8List bytes)
: key = CryptoUtils.ecPublicKeyFromDerBytes(bytes);
ECPublicKey.bytes(Uint8List bytes) : key = KeyParser.ecPublicKey(bytes);
ECPublicKey.cert(String pem) {
final x509 = X509Utils.x509CertificateFromPem(pem);
final bytes = x509.tbsCertificate?.subjectPublicKeyInfo.bytes;
if (bytes == null) {
throw JWTParseException('x509 Certificate parsing failed');
}
final bytes = KeyParser.publicKeyBytesFromCertificate(pem);
key = CryptoUtils.ecPublicKeyFromDerBytes(hexToUint8List(bytes));
key = ECPublicKey.bytes(bytes).key;
}
}

View File

@ -1,6 +1,6 @@
name: dart_jsonwebtoken
description: A dart implementation of the famous javascript library 'jsonwebtoken' (JWT).
version: 2.10.0
version: 2.11.0
repository: https://github.com/jonasroussel/dart_jsonwebtoken
homepage: https://github.com/jonasroussel/dart_jsonwebtoken#readme
@ -16,7 +16,6 @@ dependencies:
convert: ^3.1.1
collection: ^1.17.1
ed25519_edwards: ^0.3.1
basic_utils: ^5.6.1
dev_dependencies:
lints: ^2.1.1