我正在使用来自 pub.dev 的 x509b 包来执行此操作。最初的 x509 包似乎不再更新,并且使用了过时的 asn1lib 版本。在我的版本中,我同时使用 x509 和 asn1lib 本身。很确定有更清洁/更高效的方法,但这对我有用。
我也直接使用从我的根证书中提取的公钥,而不是使用整个证书,但我相信您也可以使用这些库执行该步骤。
x509 库中的 tbsCertificate 属性似乎错误,因此我使用 ASN1Parser 手动提取 TBS 证书部分。
decodePEM 函数取自 asn1lib repo 中的示例。
import 'dart:convert';
import 'dart:typed_data';
import 'package:x509b/x509.dart' as x509;
import 'package:asn1lib/asn1lib.dart';
bool verifyCertificate() {
var strX1PublicKeyInfo = "-----BEGIN PUBLIC KEY-----\nSOME PUBLIC KEY\n-----END PUBLIC KEY-----";
var strX2Certificate = "-----BEGIN CERTIFICATE-----\nSOME CERTIFICATE\n-----END CERTIFICATE-----";
var x1PublicKey = (x509.parsePem(strX1PublicKeyInfo).single as x509.SubjectPublicKeyInfo).subjectPublicKey as x509.RsaPublicKey;
var x2Certificate = x509.parsePem(strX2Certificate).single as x509.X509Certificate;
var x2CertificateDER = decodePEM(strX2Certificate);
var asn1Parser = ASN1Parser(x2CertificateDER);
var seq = asn1Parser.nextObject() as ASN1Sequence;
var tbsSequence = seq.elements[0] as ASN1Sequence;
var signature = x509.Signature(Uint8List.fromList(x2Certificate.signatureValue!));
var verifier = x1PublicKey.createVerifier(x509.algorithms.signing.rsa.sha256);
return verifier.verify(tbsSequence.encodedBytes, signature)
}
Uint8List decodePEM(pem) {
var startsWith = [
'-----BEGIN PUBLIC KEY-----',
'-----BEGIN PRIVATE KEY-----',
'-----BEGIN CERTIFICATE-----',
];
var endsWith = [
'-----END PUBLIC KEY-----',
'-----END PRIVATE KEY-----',
'-----END CERTIFICATE-----'
];
//HACK
for (var s in startsWith) {
if (pem.startsWith(s)) pem = pem.substring(s.length);
}
for (var s in endsWith) {
if (pem.endsWith(s)) pem = pem.substring(0, pem.length - s.length);
}
//Dart base64 decoder does not support line breaks
pem = pem.replaceAll('\n', '');
pem = pem.replaceAll('\r', '');
return Uint8List.fromList(base64.decode(pem));
}