mirror of
https://github.com/jonasroussel/dart_jsonwebtoken.git
synced 2025-06-22 11:48:11 +08:00
v2.7.0
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
## 2.7.0
|
||||||
|
|
||||||
|
- `parsing.dart` has been replaced by more accurate CryptoUtils functions `https://github.com/Ephenodrom/Dart-Basic-Utils`
|
||||||
|
- Fixing `_ECDSAAlgorithm.sign` method that did not filling the gap in the ECDSA curve signatures
|
||||||
|
|
||||||
## 2.6.4
|
## 2.6.4
|
||||||
|
|
||||||
- Fixing `ECPrivateKey.raw` initialize `size`
|
- Fixing `ECPrivateKey.raw` initialize `size`
|
||||||
|
@ -4,4 +4,3 @@ export 'src/jwt.dart';
|
|||||||
export 'src/errors.dart';
|
export 'src/errors.dart';
|
||||||
export 'src/algorithms.dart';
|
export 'src/algorithms.dart';
|
||||||
export 'src/keys.dart';
|
export 'src/keys.dart';
|
||||||
export 'src/parser.dart';
|
|
||||||
|
@ -241,10 +241,21 @@ class _ECDSAAlgorithm extends JWTAlgorithm {
|
|||||||
Uint8List.fromList(body),
|
Uint8List.fromList(body),
|
||||||
) as pc.ECSignature;
|
) as pc.ECSignature;
|
||||||
|
|
||||||
|
final rBytes = bigIntToBytes(signature.r).toList();
|
||||||
|
while (rBytes.length < 32) {
|
||||||
|
rBytes.add(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final sBytes = bigIntToBytes(signature.s).toList();
|
||||||
|
while (sBytes.length < 32) {
|
||||||
|
sBytes.add(0);
|
||||||
|
}
|
||||||
|
|
||||||
final len = privateKey.size;
|
final len = privateKey.size;
|
||||||
final bytes = Uint8List(len * 2);
|
final bytes = Uint8List(len * 2);
|
||||||
bytes.setRange(0, len, bigIntToBytes(signature.r).toList().reversed);
|
|
||||||
bytes.setRange(len, len * 2, bigIntToBytes(signature.s).toList().reversed);
|
bytes.setRange(0, len, rBytes.reversed);
|
||||||
|
bytes.setRange(len, len * 2, sBytes.reversed);
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
1161
lib/src/crypto_utils.dart
Normal file
1161
lib/src/crypto_utils.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -49,4 +49,7 @@ class JWTUndefinedError extends JWTError {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'JWTUndefinedError: $message';
|
String toString() => 'JWTUndefinedError: $message';
|
||||||
|
|
||||||
|
@override
|
||||||
|
StackTrace? get stackTrace => error.stackTrace;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import 'package:pointycastle/pointycastle.dart' as pc;
|
|||||||
|
|
||||||
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
|
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
|
||||||
import 'errors.dart';
|
import 'errors.dart';
|
||||||
import 'parser.dart';
|
import 'crypto_utils.dart';
|
||||||
|
|
||||||
abstract class JWTKey {}
|
abstract class JWTKey {}
|
||||||
|
|
||||||
@ -18,9 +18,11 @@ class RSAPrivateKey extends JWTKey {
|
|||||||
late pc.RSAPrivateKey key;
|
late pc.RSAPrivateKey key;
|
||||||
|
|
||||||
RSAPrivateKey(String pem) {
|
RSAPrivateKey(String pem) {
|
||||||
final _key = parseRSAPrivateKeyPEM(pem);
|
if (pem.startsWith(CryptoUtils.BEGIN_RSA_PRIVATE_KEY)) {
|
||||||
if (_key == null) throw JWTParseError('RSAPrivateKey is invalid');
|
key = CryptoUtils.rsaPrivateKeyFromPemPkcs1(pem);
|
||||||
key = _key;
|
} else {
|
||||||
|
key = CryptoUtils.rsaPrivateKeyFromPem(pem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RSAPrivateKey.raw(pc.RSAPrivateKey _key) : key = _key;
|
RSAPrivateKey.raw(pc.RSAPrivateKey _key) : key = _key;
|
||||||
@ -32,9 +34,11 @@ class RSAPublicKey extends JWTKey {
|
|||||||
late pc.RSAPublicKey key;
|
late pc.RSAPublicKey key;
|
||||||
|
|
||||||
RSAPublicKey(String pem) {
|
RSAPublicKey(String pem) {
|
||||||
final _key = parseRSAPublicKeyPEM(pem);
|
if (pem.startsWith(CryptoUtils.BEGIN_RSA_PUBLIC_KEY)) {
|
||||||
if (_key == null) throw JWTParseError('RSAPublicKey is invalid');
|
key = CryptoUtils.rsaPublicKeyFromPemPkcs1(pem);
|
||||||
key = _key;
|
} else {
|
||||||
|
key = CryptoUtils.rsaPublicKeyFromPem(pem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RSAPublicKey.raw(pc.RSAPublicKey _key) : key = _key;
|
RSAPublicKey.raw(pc.RSAPublicKey _key) : key = _key;
|
||||||
@ -47,10 +51,9 @@ class ECPrivateKey extends JWTKey {
|
|||||||
late int size;
|
late int size;
|
||||||
|
|
||||||
ECPrivateKey(String pem) {
|
ECPrivateKey(String pem) {
|
||||||
final _key = parseECPrivateKeyPEM(pem);
|
final _key = CryptoUtils.ecPrivateKeyFromPem(pem);
|
||||||
final _params = _key?.parameters;
|
final _params = _key.parameters;
|
||||||
|
|
||||||
if (_key == null) throw JWTParseError('ECPrivateKey is invalid');
|
|
||||||
if (_params == null) {
|
if (_params == null) {
|
||||||
throw JWTParseError('ECPrivateKey parameters are invalid');
|
throw JWTParseError('ECPrivateKey parameters are invalid');
|
||||||
}
|
}
|
||||||
@ -79,9 +82,7 @@ class ECPublicKey extends JWTKey {
|
|||||||
late pc.ECPublicKey key;
|
late pc.ECPublicKey key;
|
||||||
|
|
||||||
ECPublicKey(String pem) {
|
ECPublicKey(String pem) {
|
||||||
final _key = parseECPublicKeyPEM(pem);
|
key = CryptoUtils.ecPublicKeyFromPem(pem);
|
||||||
if (_key == null) throw JWTParseError('ECPublicKey is invalid');
|
|
||||||
key = _key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ECPublicKey.raw(pc.ECPublicKey _key) : key = _key;
|
ECPublicKey.raw(pc.ECPublicKey _key) : key = _key;
|
||||||
|
@ -1,326 +0,0 @@
|
|||||||
import 'dart:typed_data';
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:pointycastle/pointycastle.dart';
|
|
||||||
import 'package:pointycastle/ecc/ecc_fp.dart' as ecc_fp;
|
|
||||||
|
|
||||||
import 'utils.dart';
|
|
||||||
|
|
||||||
// RSA Private Key -> PKCS#1 format
|
|
||||||
const String _pkcs1RSAPrivateHeader = '-----BEGIN RSA PRIVATE KEY-----';
|
|
||||||
const String _pkcs1RSAPrivateFooter = '-----END RSA PRIVATE KEY-----';
|
|
||||||
|
|
||||||
// RSA Private Key -> PKCS#8 format
|
|
||||||
const String _pkcs8RSAPrivateHeader = '-----BEGIN PRIVATE KEY-----';
|
|
||||||
const String _pkcs8RSAPrivateFooter = '-----END PRIVATE KEY-----';
|
|
||||||
|
|
||||||
// RSA Public Key -> PKCS#1 format
|
|
||||||
const String _pkcs1RSAPublicHeader = '-----BEGIN RSA PUBLIC KEY-----';
|
|
||||||
const String _pkcs1RSAPublicFooter = '-----END RSA PUBLIC KEY-----';
|
|
||||||
|
|
||||||
// RSA Public Key -> PKCS#1 format
|
|
||||||
const String _pkcs8RSAPublicHeader = '-----BEGIN PUBLIC KEY-----';
|
|
||||||
const String _pkcs8RSAPublicFooter = '-----END PUBLIC KEY-----';
|
|
||||||
|
|
||||||
// ECDSA Private Key -> SEC 1 format
|
|
||||||
const String _sec1ECPrivateHeader = '-----BEGIN EC PRIVATE KEY-----';
|
|
||||||
const String _sec1ECPrivateFooter = '-----END EC PRIVATE KEY-----';
|
|
||||||
|
|
||||||
// ECDSA Private Key -> PKCS#8 format
|
|
||||||
const String _pkcs8ECPrivateHeader = '-----BEGIN PRIVATE KEY-----';
|
|
||||||
const String _pkcs8ECPrivateFooter = '-----END PRIVATE KEY-----';
|
|
||||||
|
|
||||||
// ECDSA Public Key -> PKCS#8 format
|
|
||||||
const String _pkcs8ECPublicHeader = '-----BEGIN PUBLIC KEY-----';
|
|
||||||
const String _pkcs8ECPublicFooter = '-----END PUBLIC KEY-----';
|
|
||||||
|
|
||||||
// ECDSA Curves OID to DomainName
|
|
||||||
const Map<String, String> _ecCurves = {
|
|
||||||
'1.2.840.10045.3.1.7': 'prime256v1', // P-256
|
|
||||||
'1.3.132.0.10': 'secp256k1', // P-256
|
|
||||||
'1.3.132.0.34': 'secp384r1', // P-384
|
|
||||||
'1.3.132.0.35': 'secp521r1', // P-512
|
|
||||||
};
|
|
||||||
|
|
||||||
/// RSA Private Key -> PKCS#1 parser
|
|
||||||
RSAPrivateKey? _pkcs1RSAPrivateKey(Uint8List bytes) {
|
|
||||||
final parser = ASN1Parser(bytes);
|
|
||||||
final seq = parser.nextObject() as ASN1Sequence;
|
|
||||||
final values = seq.elements?.cast<ASN1Integer>();
|
|
||||||
|
|
||||||
if (values == null) return null;
|
|
||||||
|
|
||||||
final modulus = values[1].integer;
|
|
||||||
final privateExponent = values[3].integer;
|
|
||||||
final prime1 = values[4].integer;
|
|
||||||
final prime2 = values[5].integer;
|
|
||||||
|
|
||||||
if (modulus == null ||
|
|
||||||
privateExponent == null ||
|
|
||||||
prime1 == null ||
|
|
||||||
prime2 == null) return null;
|
|
||||||
|
|
||||||
return RSAPrivateKey(
|
|
||||||
modulus,
|
|
||||||
privateExponent,
|
|
||||||
prime1,
|
|
||||||
prime2,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// RSA Private Key -> PKCS#8 parser
|
|
||||||
RSAPrivateKey? _pkcs8RSAPrivateKey(Uint8List bytes) {
|
|
||||||
final parser = ASN1Parser(bytes);
|
|
||||||
final seq = parser.nextObject() as ASN1Sequence;
|
|
||||||
|
|
||||||
final keySeq = seq.elements?[2] as ASN1OctetString?;
|
|
||||||
if (keySeq == null) return null;
|
|
||||||
final keyParser = ASN1Parser(keySeq.octets);
|
|
||||||
|
|
||||||
final valuesSeq = keyParser.nextObject() as ASN1Sequence;
|
|
||||||
final values = valuesSeq.elements?.cast<ASN1Integer>();
|
|
||||||
|
|
||||||
if (values == null) return null;
|
|
||||||
|
|
||||||
final modulus = values[1].integer;
|
|
||||||
final privateExponent = values[3].integer;
|
|
||||||
final prime1 = values[4].integer;
|
|
||||||
final prime2 = values[5].integer;
|
|
||||||
|
|
||||||
if (modulus == null ||
|
|
||||||
privateExponent == null ||
|
|
||||||
prime1 == null ||
|
|
||||||
prime2 == null) return null;
|
|
||||||
|
|
||||||
return RSAPrivateKey(
|
|
||||||
modulus,
|
|
||||||
privateExponent,
|
|
||||||
prime1,
|
|
||||||
prime2,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// RSA Public Key -> PKCS#1 parser
|
|
||||||
RSAPublicKey? _pkcs1RSAPublicKey(Uint8List bytes) {
|
|
||||||
final parser = ASN1Parser(bytes);
|
|
||||||
final seq = parser.nextObject() as ASN1Sequence;
|
|
||||||
final values = seq.elements?.cast<ASN1Integer>();
|
|
||||||
|
|
||||||
if (values == null) return null;
|
|
||||||
|
|
||||||
final modulus = values[0].integer;
|
|
||||||
final publicExponent = values[1].integer;
|
|
||||||
|
|
||||||
if (modulus == null || publicExponent == null) return null;
|
|
||||||
|
|
||||||
return RSAPublicKey(
|
|
||||||
modulus,
|
|
||||||
publicExponent,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// RSA Public Key -> PKCS#8 parser
|
|
||||||
RSAPublicKey? _pkcs8RSAPublicKey(Uint8List bytes) {
|
|
||||||
final parser = ASN1Parser(bytes);
|
|
||||||
final seq = parser.nextObject() as ASN1Sequence;
|
|
||||||
|
|
||||||
final keySeq = seq.elements?[1] as ASN1BitString?;
|
|
||||||
if (keySeq == null || keySeq.stringValues == null) return null;
|
|
||||||
final keyParser = ASN1Parser(Uint8List.fromList(keySeq.stringValues!));
|
|
||||||
|
|
||||||
final valuesSeq = keyParser.nextObject() as ASN1Sequence;
|
|
||||||
final values = valuesSeq.elements?.cast<ASN1Integer>();
|
|
||||||
|
|
||||||
if (values == null) return null;
|
|
||||||
|
|
||||||
final modulus = values[0].integer;
|
|
||||||
final publicExponent = values[1].integer;
|
|
||||||
|
|
||||||
if (modulus == null || publicExponent == null) return null;
|
|
||||||
|
|
||||||
return RSAPublicKey(modulus, publicExponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ECDSA Private Key -> SEC 1 parser
|
|
||||||
ECPrivateKey? _sec1ECPrivateKey(Uint8List bytes) {
|
|
||||||
final parser = ASN1Parser(bytes);
|
|
||||||
final seq = parser.nextObject() as ASN1Sequence;
|
|
||||||
|
|
||||||
final privateKey = seq.elements?[1] as ASN1OctetString?;
|
|
||||||
if (privateKey == null) return null;
|
|
||||||
|
|
||||||
final params = seq.elements?[2];
|
|
||||||
if (params == null || params.valueBytes == null) return null;
|
|
||||||
final paramsParser = ASN1Parser(params.valueBytes);
|
|
||||||
final oid = (paramsParser.nextObject() as ASN1ObjectIdentifier)
|
|
||||||
.objectIdentifierAsString;
|
|
||||||
final curve = _ecCurves[oid];
|
|
||||||
|
|
||||||
if (privateKey.valueBytes == null || curve == null) return null;
|
|
||||||
|
|
||||||
return ECPrivateKey(
|
|
||||||
decodeBigInt(privateKey.valueBytes!),
|
|
||||||
ECDomainParameters(curve),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ECDSA Private Key -> PKCS#8 parser
|
|
||||||
ECPrivateKey? _pkcs8ECPrivateKey(Uint8List bytes) {
|
|
||||||
final parser = ASN1Parser(bytes);
|
|
||||||
final seq = parser.nextObject() as ASN1Sequence;
|
|
||||||
if (seq.elements == null) return null;
|
|
||||||
|
|
||||||
final oidSeq = seq.elements?[1] as ASN1Sequence?;
|
|
||||||
if (oidSeq == null || oidSeq.elements == null) return null;
|
|
||||||
final oid =
|
|
||||||
(oidSeq.elements![1] as ASN1ObjectIdentifier).objectIdentifierAsString;
|
|
||||||
final curve = _ecCurves[oid];
|
|
||||||
|
|
||||||
final privateKeyParser = ASN1Parser(seq.elements![2].valueBytes);
|
|
||||||
final privateKeySeq = privateKeyParser.nextObject() as ASN1Sequence;
|
|
||||||
if (privateKeySeq.elements == null) return null;
|
|
||||||
final privateKey = (privateKeySeq.elements![1] as ASN1OctetString);
|
|
||||||
|
|
||||||
if (privateKey.valueBytes == null || curve == null) return null;
|
|
||||||
|
|
||||||
return ECPrivateKey(
|
|
||||||
decodeBigInt(privateKey.valueBytes!),
|
|
||||||
ECDomainParameters(curve),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ECDSA Public Key -> PKCS#8 parser
|
|
||||||
ECPublicKey? _pkcs8ECPublicKey(Uint8List bytes) {
|
|
||||||
final parser = ASN1Parser(bytes);
|
|
||||||
final seq = parser.nextObject() as ASN1Sequence;
|
|
||||||
if (seq.elements == null) return null;
|
|
||||||
|
|
||||||
final oidSeq = seq.elements![0] as ASN1Sequence;
|
|
||||||
if (oidSeq.elements == null) return null;
|
|
||||||
final oid =
|
|
||||||
(oidSeq.elements![1] as ASN1ObjectIdentifier).objectIdentifierAsString;
|
|
||||||
final curve = _ecCurves[oid];
|
|
||||||
|
|
||||||
if (curve == null) return null;
|
|
||||||
|
|
||||||
var publicKeyBytes = seq.elements![1].valueBytes;
|
|
||||||
if (publicKeyBytes == null) return null;
|
|
||||||
if (publicKeyBytes[0] == 0) {
|
|
||||||
publicKeyBytes = publicKeyBytes.sublist(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
final compressed = publicKeyBytes[0] != 4;
|
|
||||||
final x = publicKeyBytes.sublist(1, (publicKeyBytes.length / 2).round());
|
|
||||||
final y = publicKeyBytes.sublist(1 + x.length, publicKeyBytes.length);
|
|
||||||
final bigX = decodeBigIntWithSign(1, x);
|
|
||||||
final bigY = decodeBigIntWithSign(1, y);
|
|
||||||
final params = ECDomainParameters(curve);
|
|
||||||
|
|
||||||
return 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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse RSA private key from pem string
|
|
||||||
RSAPrivateKey? parseRSAPrivateKeyPEM(String pem) {
|
|
||||||
if (pem.contains(_pkcs1RSAPrivateHeader) &&
|
|
||||||
pem.contains(_pkcs1RSAPrivateFooter)) {
|
|
||||||
final data = pem
|
|
||||||
.substring(
|
|
||||||
pem.indexOf(_pkcs1RSAPrivateHeader) + _pkcs1RSAPrivateHeader.length,
|
|
||||||
pem.indexOf(_pkcs1RSAPrivateFooter),
|
|
||||||
)
|
|
||||||
.replaceAll(RegExp(r'[\n\r ]'), '');
|
|
||||||
|
|
||||||
return _pkcs1RSAPrivateKey(base64.decode(data));
|
|
||||||
} else if (pem.contains(_pkcs8RSAPrivateHeader) &&
|
|
||||||
pem.contains(_pkcs8RSAPrivateFooter)) {
|
|
||||||
final data = pem
|
|
||||||
.substring(
|
|
||||||
pem.indexOf(_pkcs8RSAPrivateHeader) + _pkcs8RSAPrivateHeader.length,
|
|
||||||
pem.indexOf(_pkcs8RSAPrivateFooter),
|
|
||||||
)
|
|
||||||
.replaceAll(RegExp(r'[\n\r ]'), '');
|
|
||||||
|
|
||||||
return _pkcs8RSAPrivateKey(base64.decode(data));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse RSA public key from pem string
|
|
||||||
RSAPublicKey? parseRSAPublicKeyPEM(String pem) {
|
|
||||||
if (pem.contains(_pkcs1RSAPublicHeader) &&
|
|
||||||
pem.contains(_pkcs1RSAPublicFooter)) {
|
|
||||||
final data = pem
|
|
||||||
.substring(
|
|
||||||
pem.indexOf(_pkcs1RSAPublicHeader) + _pkcs1RSAPublicHeader.length,
|
|
||||||
pem.indexOf(_pkcs1RSAPublicFooter),
|
|
||||||
)
|
|
||||||
.replaceAll(RegExp(r'[\n\r ]'), '');
|
|
||||||
|
|
||||||
return _pkcs1RSAPublicKey(base64.decode(data));
|
|
||||||
} else if (pem.contains(_pkcs8RSAPublicHeader) &&
|
|
||||||
pem.contains(_pkcs8RSAPublicFooter)) {
|
|
||||||
final data = pem
|
|
||||||
.substring(
|
|
||||||
pem.indexOf(_pkcs8RSAPublicHeader) + _pkcs8RSAPublicHeader.length,
|
|
||||||
pem.indexOf(_pkcs8RSAPublicFooter),
|
|
||||||
)
|
|
||||||
.replaceAll(RegExp(r'[\n\r ]'), '');
|
|
||||||
|
|
||||||
return _pkcs8RSAPublicKey(base64.decode(data));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse ECDSA private key from pem string
|
|
||||||
ECPrivateKey? parseECPrivateKeyPEM(String pem) {
|
|
||||||
if (pem.contains(_sec1ECPrivateHeader) &&
|
|
||||||
pem.contains(_sec1ECPrivateFooter)) {
|
|
||||||
final data = pem
|
|
||||||
.substring(
|
|
||||||
pem.indexOf(_sec1ECPrivateHeader) + _sec1ECPrivateHeader.length,
|
|
||||||
pem.indexOf(_sec1ECPrivateFooter),
|
|
||||||
)
|
|
||||||
.replaceAll(RegExp(r'[\n\r ]'), '');
|
|
||||||
|
|
||||||
return _sec1ECPrivateKey(base64.decode(data));
|
|
||||||
} else if (pem.contains(_pkcs8ECPrivateHeader) &&
|
|
||||||
pem.contains(_pkcs8ECPrivateFooter)) {
|
|
||||||
final data = pem
|
|
||||||
.substring(
|
|
||||||
pem.indexOf(_pkcs8ECPrivateHeader) + _pkcs8ECPrivateHeader.length,
|
|
||||||
pem.indexOf(_pkcs8ECPrivateFooter),
|
|
||||||
)
|
|
||||||
.replaceAll(RegExp(r'[\n\r ]'), '');
|
|
||||||
|
|
||||||
return _pkcs8ECPrivateKey(base64.decode(data));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse ECDSA public key from pem string
|
|
||||||
ECPublicKey? parseECPublicKeyPEM(String pem) {
|
|
||||||
if (pem.contains(_pkcs8ECPublicHeader) &&
|
|
||||||
pem.contains(_pkcs8ECPublicFooter)) {
|
|
||||||
final data = pem
|
|
||||||
.substring(
|
|
||||||
pem.indexOf(_pkcs8ECPublicHeader) + _pkcs8ECPublicHeader.length,
|
|
||||||
pem.indexOf(_pkcs8ECPublicFooter),
|
|
||||||
)
|
|
||||||
.replaceAll(RegExp(r'[\n\r ]'), '');
|
|
||||||
|
|
||||||
return _pkcs8ECPublicKey(base64.decode(data));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
name: dart_jsonwebtoken
|
name: dart_jsonwebtoken
|
||||||
description: A dart implementation of the famous javascript library 'jsonwebtoken' (JWT).
|
description: A dart implementation of the famous javascript library 'jsonwebtoken' (JWT).
|
||||||
version: 2.6.4
|
version: 2.7.0
|
||||||
repository: https://github.com/jonasroussel/dart_jsonwebtoken
|
repository: https://github.com/jonasroussel/dart_jsonwebtoken
|
||||||
homepage: https://github.com/jonasroussel/dart_jsonwebtoken#readme
|
homepage: https://github.com/jonasroussel/dart_jsonwebtoken#readme
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user