Skip to content

Commit c4375c8

Browse files
authored
Merge pull request #116 from timoxd7/der-encoding
Added DER Bytes encoding as alternative to PEM
2 parents 45ed0a3 + d18a0f7 commit c4375c8

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ AsymmetricKeyPair generateRSAKeyPair({int keySize = 2048});
287287
AsymmetricKeyPair generateEcKeyPair({String curve = 'prime256v1'});
288288
String encodeRSAPublicKeyToPem(RSAPublicKey publicKey);
289289
String encodeRSAPrivateKeyToPem(RSAPrivateKey rsaPrivateKey);
290+
Uint8List encodeRSAPublicKeyToDERBytes(RSAPublicKey publicKey);
291+
Uint8List encodeRSAPrivateKeyToDERBytes(RSAPrivateKey privateKey);
290292
RSAPrivateKey rsaPrivateKeyFromPem(String pem);
291293
RSAPublicKey rsaPublicKeyFromPem(String pem);
292294
RSAPrivateKey rsaPrivateKeyFromDERBytes(Uint8List bytes);

lib/src/CryptoUtils.dart

+36-8
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,9 @@ class CryptoUtils {
261261
}
262262

263263
///
264-
/// Enode the given [publicKey] to PEM format using the PKCS#8 standard.
264+
/// Enode the given [publicKey] to DER bytes using the PKCS#8 standard.
265265
///
266-
static String encodeRSAPublicKeyToPem(RSAPublicKey publicKey) {
266+
static Uint8List encodeRSAPublicKeyToDERBytes(RSAPublicKey publicKey) {
267267
var algorithmSeq = ASN1Sequence();
268268
var paramsAsn1Obj = ASN1Object.fromBytes(Uint8List.fromList([0x5, 0x0]));
269269
algorithmSeq.add(ASN1ObjectIdentifier.fromName('rsaEncryption'));
@@ -278,7 +278,15 @@ class CryptoUtils {
278278
var topLevelSeq = ASN1Sequence();
279279
topLevelSeq.add(algorithmSeq);
280280
topLevelSeq.add(publicKeySeqBitString);
281-
var dataBase64 = base64.encode(topLevelSeq.encode());
281+
282+
return topLevelSeq.encode();
283+
}
284+
285+
///
286+
/// Enode the given [publicKey] to PEM format using the PKCS#8 standard.
287+
///
288+
static String encodeRSAPublicKeyToPem(RSAPublicKey publicKey) {
289+
var dataBase64 = base64.encode(encodeRSAPublicKeyToDERBytes(publicKey));
282290
var chunks = StringUtils.chunk(dataBase64, 64);
283291

284292
return '$BEGIN_PUBLIC_KEY\n${chunks.join('\n')}\n$END_PUBLIC_KEY';
@@ -359,7 +367,7 @@ class CryptoUtils {
359367
}
360368

361369
///
362-
/// Enode the given [rsaPrivateKey] to PEM format using the PKCS#8 standard.
370+
/// Enode the given [rsaPrivateKey] to DER Bytes using the PKCS#8 standard.
363371
///
364372
/// The ASN1 structure is decripted at <https://tools.ietf.org/html/rfc5208>.
365373
/// ```
@@ -370,7 +378,7 @@ class CryptoUtils {
370378
/// }
371379
/// ```
372380
///
373-
static String encodeRSAPrivateKeyToPem(RSAPrivateKey rsaPrivateKey) {
381+
static Uint8List encodeRSAPrivateKeyToDERBytes(RSAPrivateKey rsaPrivateKey) {
374382
var version = ASN1Integer(BigInt.from(0));
375383

376384
var algorithmSeq = ASN1Sequence();
@@ -411,7 +419,25 @@ class CryptoUtils {
411419
topLevelSeq.add(version);
412420
topLevelSeq.add(algorithmSeq);
413421
topLevelSeq.add(publicKeySeqOctetString);
414-
var dataBase64 = base64.encode(topLevelSeq.encode());
422+
423+
return topLevelSeq.encode();
424+
}
425+
426+
///
427+
/// Enode the given [rsaPrivateKey] to PEM format using the PKCS#8 standard.
428+
///
429+
/// The ASN1 structure is decripted at <https://tools.ietf.org/html/rfc5208>.
430+
/// ```
431+
/// PrivateKeyInfo ::= SEQUENCE {
432+
/// version Version,
433+
/// algorithm AlgorithmIdentifier,
434+
/// PrivateKey BIT STRING
435+
/// }
436+
/// ```
437+
///
438+
static String encodeRSAPrivateKeyToPem(RSAPrivateKey rsaPrivateKey) {
439+
var dataBase64 =
440+
base64.encode(encodeRSAPrivateKeyToDERBytes(rsaPrivateKey));
415441
var chunks = StringUtils.chunk(dataBase64, 64);
416442
return '$BEGIN_PRIVATE_KEY\n${chunks.join('\n')}\n$END_PRIVATE_KEY';
417443
}
@@ -1179,8 +1205,10 @@ class CryptoUtils {
11791205
///
11801206
static String encodePrivateEcdsaKeyToPkcs8(ECPrivateKey privateKey) {
11811207
final privateKeyPem = CryptoUtils.encodeEcPrivateKeyToPem(privateKey);
1182-
final base64Encoded = base64.encode(ASN1PrivateKeyInfo.fromEccPem(privateKeyPem).encode());
1183-
final base64Formatted = base64Encoded.replaceAllMapped(RegExp(r".{64}"), (match) => "${match.group(0)}\n");
1208+
final base64Encoded =
1209+
base64.encode(ASN1PrivateKeyInfo.fromEccPem(privateKeyPem).encode());
1210+
final base64Formatted = base64Encoded.replaceAllMapped(
1211+
RegExp(r".{64}"), (match) => "${match.group(0)}\n");
11841212

11851213
return '$BEGIN_PRIVATE_KEY\n$base64Formatted\n$END_PRIVATE_KEY';
11861214
}

test/crypto_utils_test.dart

+20-3
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ sF0zEAHkQoYVBEhrfAHOLYkE3u08+q2tug==
151151
expect(pem.endsWith('-----END PRIVATE KEY-----'), true);
152152
});
153153

154+
test('Test encodeRSAPrivateKeyToDERBytes', () {
155+
var pair = CryptoUtils.generateRSAKeyPair();
156+
var derBytes = CryptoUtils.encodeRSAPrivateKeyToDERBytes(
157+
pair.privateKey as RSAPrivateKey);
158+
var privateKey = CryptoUtils.rsaPrivateKeyFromDERBytes(derBytes);
159+
expect(privateKey, pair.privateKey);
160+
});
161+
154162
test('Test encodeRSAPublicKeyToPem', () {
155163
var pair = CryptoUtils.generateRSAKeyPair();
156164
var pem =
@@ -159,6 +167,14 @@ sF0zEAHkQoYVBEhrfAHOLYkE3u08+q2tug==
159167
expect(pem.endsWith('-----END PUBLIC KEY-----'), true);
160168
});
161169

170+
test('Test encodeRSAPublicKeyToDERBytes', () {
171+
var pair = CryptoUtils.generateRSAKeyPair();
172+
var derBytes = CryptoUtils.encodeRSAPublicKeyToDERBytes(
173+
pair.publicKey as RSAPublicKey);
174+
var publicKey = CryptoUtils.rsaPublicKeyFromDERBytes(derBytes);
175+
expect(publicKey, pair.publicKey);
176+
});
177+
162178
test('Test encodeRSAPrivateKeyToPemPkcs1', () {
163179
var pair = CryptoUtils.generateRSAKeyPair();
164180
var pem = CryptoUtils.encodeRSAPrivateKeyToPemPkcs1(
@@ -431,9 +447,10 @@ sF0zEAHkQoYVBEhrfAHOLYkE3u08+q2tug==
431447
});
432448

433449
test('Test encodeEcPrivateKeyToPkcs8', () {
434-
var ecdsaKeypair = CryptoUtils.generateEcKeyPair();
435-
var ecPrivateKeyPkcs8 = CryptoUtils.encodePrivateEcdsaKeyToPkcs8(ecdsaKeypair.privateKey as ECPrivateKey);
450+
var ecdsaKeypair = CryptoUtils.generateEcKeyPair();
451+
var ecPrivateKeyPkcs8 = CryptoUtils.encodePrivateEcdsaKeyToPkcs8(
452+
ecdsaKeypair.privateKey as ECPrivateKey);
436453

437-
expect(ecPrivateKeyPkcs8.startsWith('-----BEGIN PRIVATE KEY-----'), true);
454+
expect(ecPrivateKeyPkcs8.startsWith('-----BEGIN PRIVATE KEY-----'), true);
438455
});
439456
}

0 commit comments

Comments
 (0)