fromRawBytes static method
Implementation
static Future<p2pkeys.PrivateKey> fromRawBytes(Uint8List bytes) async {
if (bytes.isEmpty) {
throw FormatException('Empty byte array provided');
}
try {
// Debug information
final parser = pc.ASN1Parser(bytes);
final asn1Object = parser.nextObject();
if (asn1Object is! pc.ASN1Sequence) {
throw FormatException(
'Expected ASN.1 SEQUENCE but got: ${asn1Object.runtimeType}');
}
final asn1Sequence = asn1Object;
// Parse the ASN.1 structure according to PKCS#1
// RSAPrivateKey ::= SEQUENCE {
// version Version,
// modulus INTEGER, -- n
// publicExponent INTEGER, -- e
// privateExponent INTEGER, -- d
// prime1 INTEGER, -- p
// prime2 INTEGER, -- q
// exponent1 INTEGER, -- d mod (p-1)
// exponent2 INTEGER, -- d mod (q-1)
// coefficient INTEGER, -- (inverse of q) mod p
// otherPrimeInfos OtherPrimeInfos OPTIONAL
// }
if (asn1Sequence.elements == null || asn1Sequence.elements!.length < 9) {
throw FormatException(
'RSA private key sequence does not contain required elements. Found: ${asn1Sequence.elements?.length ?? 0}');
}
// Validate and extract each element with proper type checking
if (asn1Sequence.elements![0] is! pc.ASN1Integer) {
throw FormatException('Expected version to be ASN1Integer');
}
final version = (asn1Sequence.elements![0] as pc.ASN1Integer).integer;
if (version != BigInt.from(0)) {
throw FormatException('Unsupported RSA private key version: $version');
}
// Extract and check all the required integers
final elements = <BigInt?>[];
for (int i = 0; i < 9; i++) {
if (asn1Sequence.elements![i] is! pc.ASN1Integer) {
throw FormatException(
'Expected ASN1Integer at position $i but got ${asn1Sequence.elements![i].runtimeType}');
}
elements.add((asn1Sequence.elements![i] as pc.ASN1Integer).integer);
}
final modulus = elements[1];
final publicExponent = elements[2];
final privateExponent = elements[3];
final p = elements[4];
final q = elements[5];
final dP = elements[6];
final dQ = elements[7];
final qInv = elements[8];
// Validate that no required values are null
if (modulus == null ||
publicExponent == null ||
privateExponent == null ||
p == null ||
q == null ||
dP == null ||
dQ == null ||
qInv == null) {
throw FormatException('One or more required RSA parameters are null');
}
final privateKey = pc.RSAPrivateKey(modulus, privateExponent, p, q);
final publicKey = pc.RSAPublicKey(
modulus,
publicExponent,
);
return RsaPrivateKey(privateKey, RsaPublicKey(publicKey));
} catch (e) {
if (e is FormatException) {
rethrow;
}
throw FormatException('Failed to parse RSA private key: $e');
}
}