encodeRSAPrivateKeyToPem static method

String encodeRSAPrivateKeyToPem(
  1. RSAPrivateKey rsaPrivateKey
)

Enode the given rsaPrivateKey to PEM format using the PKCS#8 standard.

The ASN1 structure is decripted at tools.ietf.org/html/rfc5208.

PrivateKeyInfo ::= SEQUENCE {
  version         Version,
  algorithm       AlgorithmIdentifier,
  PrivateKey      BIT STRING
}

Implementation

static String encodeRSAPrivateKeyToPem(RSAPrivateKey rsaPrivateKey) {
  var version = ASN1Integer(BigInt.from(0));

  var algorithmSeq = ASN1Sequence();
  var algorithmAsn1Obj = ASN1Object.fromBytes(Uint8List.fromList(
      [0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1]));
  var paramsAsn1Obj = ASN1Object.fromBytes(Uint8List.fromList([0x5, 0x0]));
  algorithmSeq.add(algorithmAsn1Obj);
  algorithmSeq.add(paramsAsn1Obj);

  var privateKeySeq = ASN1Sequence();
  var modulus = ASN1Integer(rsaPrivateKey.n);
  var publicExponent = ASN1Integer(BigInt.parse('65537'));
  var privateExponent = ASN1Integer(rsaPrivateKey.privateExponent);
  var p = ASN1Integer(rsaPrivateKey.p);
  var q = ASN1Integer(rsaPrivateKey.q);
  var dP =
      rsaPrivateKey.privateExponent! % (rsaPrivateKey.p! - BigInt.from(1));
  var exp1 = ASN1Integer(dP);
  var dQ =
      rsaPrivateKey.privateExponent! % (rsaPrivateKey.q! - BigInt.from(1));
  var exp2 = ASN1Integer(dQ);
  var iQ = rsaPrivateKey.q!.modInverse(rsaPrivateKey.p!);
  var co = ASN1Integer(iQ);

  privateKeySeq.add(version);
  privateKeySeq.add(modulus);
  privateKeySeq.add(publicExponent);
  privateKeySeq.add(privateExponent);
  privateKeySeq.add(p);
  privateKeySeq.add(q);
  privateKeySeq.add(exp1);
  privateKeySeq.add(exp2);
  privateKeySeq.add(co);
  var publicKeySeqOctetString =
  ASN1OctetString(octets: Uint8List.fromList(privateKeySeq.encode()));

  var topLevelSeq = ASN1Sequence();
  topLevelSeq.add(version);
  topLevelSeq.add(algorithmSeq);
  topLevelSeq.add(publicKeySeqOctetString);
  var dataBase64 = base64.encode(topLevelSeq.encode());
  var chunks = _chunk(dataBase64, 64);
  return '$BEGIN_PRIVATE_KEY\n${chunks.join('\n')}\n$END_PRIVATE_KEY';
}