Skip to content

Commit 548ef23

Browse files
authored
Add support for OpenSSL PKCS#8 private key format (#1496)
* Add support for OpenSSL PKCS#8 private key format * Update comments * Convert public key to ssh format * Convert existing keys instead of generate new keys; Use DataRow for testing * Minimize the change * Minimize the change * Fix build
1 parent 3b55ba3 commit 548ef23

13 files changed

+295
-25
lines changed

README.md

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,36 @@ The main types provided by this library are:
9696
## Public Key Authentication
9797

9898
**SSH.NET** supports the following private key formats:
99-
* RSA in OpenSSL PEM ("BEGIN RSA PRIVATE KEY") and ssh.com ("BEGIN SSH2 ENCRYPTED PRIVATE KEY") format
100-
* DSA in OpenSSL PEM ("BEGIN DSA PRIVATE KEY") and ssh.com ("BEGIN SSH2 ENCRYPTED PRIVATE KEY") format
101-
* ECDSA 256/384/521 in OpenSSL PEM format ("BEGIN EC PRIVATE KEY")
102-
* ECDSA 256/384/521, ED25519 and RSA in OpenSSH key format ("BEGIN OPENSSH PRIVATE KEY")
103-
104-
Private keys in OpenSSL PEM and ssh.com format can be encrypted using one of the following cipher methods:
99+
* RSA in
100+
* OpenSSL traditional PEM format ("BEGIN RSA PRIVATE KEY")
101+
* OpenSSL PKCS#8 PEM format ("BEGIN PRIVATE KEY", "BEGIN ENCRYPTED PRIVATE KEY")
102+
* ssh.com format ("BEGIN SSH2 ENCRYPTED PRIVATE KEY")
103+
* OpenSSH key format ("BEGIN OPENSSH PRIVATE KEY")
104+
* DSA in
105+
* OpenSSL traditional PEM format ("BEGIN DSA PRIVATE KEY")
106+
* OpenSSL PKCS#8 PEM format ("BEGIN PRIVATE KEY", "BEGIN ENCRYPTED PRIVATE KEY")
107+
* ssh.com format ("BEGIN SSH2 ENCRYPTED PRIVATE KEY")
108+
* ECDSA 256/384/521 in
109+
* OpenSSL traditional PEM format ("BEGIN EC PRIVATE KEY")
110+
* OpenSSL PKCS#8 PEM format ("BEGIN PRIVATE KEY", "BEGIN ENCRYPTED PRIVATE KEY")
111+
* OpenSSH key format ("BEGIN OPENSSH PRIVATE KEY")
112+
* ED25519 in
113+
* OpenSSL PKCS#8 PEM format ("BEGIN PRIVATE KEY", "BEGIN ENCRYPTED PRIVATE KEY")
114+
* OpenSSH key format ("BEGIN OPENSSH PRIVATE KEY")
115+
116+
Private keys in OpenSSL traditional PEM format can be encrypted using one of the following cipher methods:
105117
* DES-EDE3-CBC
106118
* DES-EDE3-CFB
107119
* DES-CBC
108120
* AES-128-CBC
109121
* AES-192-CBC
110122
* AES-256-CBC
111123

124+
Private keys in OpenSSL PKCS#8 PEM format can be encrypted using any cipher method BouncyCastle supports.
125+
126+
Private keys in ssh.com format can be encrypted using one of the following cipher methods:
127+
* 3des-cbc
128+
112129
Private keys in OpenSSH key format can be encrypted using one of the following cipher methods:
113130
* 3des-cbc
114131
* aes128-cbc

src/Renci.SshNet/PrivateKeyConnectionInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class PrivateKeyConnectionInfo : ConnectionInfo, IDisposable
2222
/// <param name="host">Connection host.</param>
2323
/// <param name="username">Connection username.</param>
2424
/// <param name="keyFiles">Connection key files.</param>
25-
public PrivateKeyConnectionInfo(string host, string username, params PrivateKeyFile[] keyFiles)
25+
public PrivateKeyConnectionInfo(string host, string username, params IPrivateKeySource[] keyFiles)
2626
: this(host, DefaultPort, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty, keyFiles)
2727
{
2828
}

src/Renci.SshNet/PrivateKeyFile.cs

Lines changed: 154 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
#nullable enable
1+
#nullable enable
22
using System;
33
using System.Collections.Generic;
44
using System.Diagnostics;
55
using System.Diagnostics.CodeAnalysis;
6+
using System.Formats.Asn1;
67
using System.Globalization;
78
using System.IO;
89
using System.Numerics;
910
using System.Security.Cryptography;
1011
using System.Text;
1112
using System.Text.RegularExpressions;
1213

14+
using Org.BouncyCastle.Asn1.EdEC;
15+
using Org.BouncyCastle.Asn1.Pkcs;
16+
using Org.BouncyCastle.Asn1.X9;
17+
using Org.BouncyCastle.Pkcs;
18+
1319
using Renci.SshNet.Common;
1420
using Renci.SshNet.Security;
1521
using Renci.SshNet.Security.Cryptography;
@@ -36,12 +42,12 @@ namespace Renci.SshNet
3642
/// <description>ECDSA 256/384/521 in OpenSSL PEM and OpenSSH key format</description>
3743
/// </item>
3844
/// <item>
39-
/// <description>ED25519 in OpenSSH key format</description>
45+
/// <description>ED25519 in OpenSSL PEM and OpenSSH key format</description>
4046
/// </item>
4147
/// </list>
4248
/// </para>
4349
/// <para>
44-
/// The following encryption algorithms are supported for OpenSSL PEM and ssh.com format:
50+
/// The following encryption algorithms are supported for OpenSSL traditional PEM:
4551
/// <list type="bullet">
4652
/// <item>
4753
/// <description>DES-EDE3-CBC</description>
@@ -62,6 +68,19 @@ namespace Renci.SshNet
6268
/// <description>AES-256-CBC</description>
6369
/// </item>
6470
/// </list>
71+
/// </para>
72+
/// <para>
73+
/// Private keys in OpenSSL PKCS#8 PEM format can be encrypted using any cipher method BouncyCastle supports.
74+
/// </para>
75+
/// <para>
76+
/// The following encryption algorithms are supported for ssh.com format:
77+
/// <list type="bullet">
78+
/// <item>
79+
/// <description>3des-cbc</description>
80+
/// </item>
81+
/// </list>
82+
/// </para>
83+
/// <para>
6584
/// The following encryption algorithms are supported for OpenSSH format:
6685
/// <list type="bullet">
6786
/// <item>
@@ -99,7 +118,7 @@ namespace Renci.SshNet
99118
/// </remarks>
100119
public partial class PrivateKeyFile : IPrivateKeySource, IDisposable
101120
{
102-
private const string PrivateKeyPattern = @"^-+ *BEGIN (?<keyName>\w+( \w+)*) PRIVATE KEY *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?<cipherName>[A-Z0-9-]+),(?<salt>[A-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?<data>([a-zA-Z0-9/+=]{1,80}\r?\n)+)(\r?\n)?-+ *END \k<keyName> PRIVATE KEY *-+";
121+
private const string PrivateKeyPattern = @"^-+ *BEGIN (?<keyName>\w+( \w+)*) *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?<cipherName>[A-Z0-9-]+),(?<salt>[A-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?<data>([a-zA-Z0-9/+=]{1,80}\r?\n)+)(\r?\n)?-+ *END \k<keyName> *-+";
103122

104123
#if NET7_0_OR_GREATER
105124
private static readonly Regex PrivateKeyRegex = GetPrivateKeyRegex();
@@ -233,6 +252,11 @@ private void Open(Stream privateKey, string? passPhrase)
233252
}
234253

235254
var keyName = privateKeyMatch.Result("${keyName}");
255+
if (!keyName.EndsWith("PRIVATE KEY", StringComparison.Ordinal))
256+
{
257+
throw new SshException("Invalid private key file.");
258+
}
259+
236260
var cipherName = privateKeyMatch.Result("${cipherName}");
237261
var salt = privateKeyMatch.Result("${salt}");
238262
var data = privateKeyMatch.Result("${data}");
@@ -288,7 +312,7 @@ private void Open(Stream privateKey, string? passPhrase)
288312

289313
switch (keyName)
290314
{
291-
case "RSA":
315+
case "RSA PRIVATE KEY":
292316
var rsaKey = new RsaKey(decryptedData);
293317
_key = rsaKey;
294318
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-rsa", _key));
@@ -297,16 +321,17 @@ private void Open(Stream privateKey, string? passPhrase)
297321
_hostAlgorithms.Add(new KeyHostAlgorithm("rsa-sha2-256", _key, new RsaDigitalSignature(rsaKey, HashAlgorithmName.SHA256)));
298322
#pragma warning restore CA2000 // Dispose objects before losing scope
299323
break;
300-
case "DSA":
324+
case "DSA PRIVATE KEY":
301325
_key = new DsaKey(decryptedData);
302326
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-dss", _key));
303327
break;
304-
case "EC":
328+
case "EC PRIVATE KEY":
305329
_key = new EcdsaKey(decryptedData);
306330
_hostAlgorithms.Add(new KeyHostAlgorithm(_key.ToString(), _key));
307331
break;
308-
case "OPENSSH":
309-
_key = ParseOpenSshV1Key(decryptedData, passPhrase);
332+
case "PRIVATE KEY":
333+
var privateKeyInfo = PrivateKeyInfo.GetInstance(binaryData);
334+
_key = ParseOpenSslPkcs8PrivateKey(privateKeyInfo);
310335
if (_key is RsaKey parsedRsaKey)
311336
{
312337
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-rsa", _key));
@@ -315,13 +340,55 @@ private void Open(Stream privateKey, string? passPhrase)
315340
_hostAlgorithms.Add(new KeyHostAlgorithm("rsa-sha2-256", _key, new RsaDigitalSignature(parsedRsaKey, HashAlgorithmName.SHA256)));
316341
#pragma warning restore CA2000 // Dispose objects before losing scope
317342
}
343+
else if (_key is DsaKey parsedDsaKey)
344+
{
345+
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-dss", _key));
346+
}
318347
else
319348
{
320349
_hostAlgorithms.Add(new KeyHostAlgorithm(_key.ToString(), _key));
321350
}
322351

323352
break;
324-
case "SSH2 ENCRYPTED":
353+
case "ENCRYPTED PRIVATE KEY":
354+
var encryptedPrivateKeyInfo = EncryptedPrivateKeyInfo.GetInstance(binaryData);
355+
privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(passPhrase?.ToCharArray(), encryptedPrivateKeyInfo);
356+
_key = ParseOpenSslPkcs8PrivateKey(privateKeyInfo);
357+
if (_key is RsaKey parsedRsaKey2)
358+
{
359+
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-rsa", _key));
360+
#pragma warning disable CA2000 // Dispose objects before losing scope
361+
_hostAlgorithms.Add(new KeyHostAlgorithm("rsa-sha2-512", _key, new RsaDigitalSignature(parsedRsaKey2, HashAlgorithmName.SHA512)));
362+
_hostAlgorithms.Add(new KeyHostAlgorithm("rsa-sha2-256", _key, new RsaDigitalSignature(parsedRsaKey2, HashAlgorithmName.SHA256)));
363+
#pragma warning restore CA2000 // Dispose objects before losing scope
364+
}
365+
else if (_key is DsaKey parsedDsaKey)
366+
{
367+
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-dss", _key));
368+
}
369+
else
370+
{
371+
_hostAlgorithms.Add(new KeyHostAlgorithm(_key.ToString(), _key));
372+
}
373+
374+
break;
375+
case "OPENSSH PRIVATE KEY":
376+
_key = ParseOpenSshV1Key(decryptedData, passPhrase);
377+
if (_key is RsaKey parsedRsaKey3)
378+
{
379+
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-rsa", _key));
380+
#pragma warning disable CA2000 // Dispose objects before losing scope
381+
_hostAlgorithms.Add(new KeyHostAlgorithm("rsa-sha2-512", _key, new RsaDigitalSignature(parsedRsaKey3, HashAlgorithmName.SHA512)));
382+
_hostAlgorithms.Add(new KeyHostAlgorithm("rsa-sha2-256", _key, new RsaDigitalSignature(parsedRsaKey3, HashAlgorithmName.SHA256)));
383+
#pragma warning restore CA2000 // Dispose objects before losing scope
384+
}
385+
else
386+
{
387+
_hostAlgorithms.Add(new KeyHostAlgorithm(_key.ToString(), _key));
388+
}
389+
390+
break;
391+
case "SSH2 ENCRYPTED PRIVATE KEY":
325392
var reader = new SshDataReader(decryptedData);
326393
var magicNumber = reader.ReadUInt32();
327394
if (magicNumber != 0x3f6ff9eb)
@@ -488,8 +555,8 @@ private static byte[] DecryptKey(CipherInfo cipherInfo, byte[] cipherData, strin
488555
}
489556

490557
/// <summary>
491-
/// Parses an OpenSSH V1 key file (i.e. ED25519 key) according to the the key spec:
492-
/// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.
558+
/// Parses an OpenSSH V1 key file according to the key spec:
559+
/// <see href="https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key"/>.
493560
/// </summary>
494561
/// <param name="keyFileData">The key file data (i.e. base64 encoded data between the header/footer).</param>
495562
/// <param name="passPhrase">Passphrase or <see langword="null"/> if there isn't one.</param>
@@ -712,6 +779,81 @@ private static Key ParseOpenSshV1Key(byte[] keyFileData, string? passPhrase)
712779
return parsedKey;
713780
}
714781

782+
/// <summary>
783+
/// Parses an OpenSSL PKCS#8 key file according to RFC5208:
784+
/// <see href="https://www.rfc-editor.org/rfc/rfc5208#section-5"/>.
785+
/// </summary>
786+
/// <param name="privateKeyInfo">The <see cref="PrivateKeyInfo"/>.</param>
787+
/// <returns>
788+
/// The <see cref="Key"/>.
789+
/// </returns>
790+
/// <exception cref="SshException">Algorithm not supported.</exception>
791+
private static Key ParseOpenSslPkcs8PrivateKey(PrivateKeyInfo privateKeyInfo)
792+
{
793+
var algorithmOid = privateKeyInfo.PrivateKeyAlgorithm.Algorithm;
794+
var key = privateKeyInfo.PrivateKey.GetOctets();
795+
if (algorithmOid.Equals(PkcsObjectIdentifiers.RsaEncryption))
796+
{
797+
return new RsaKey(key);
798+
}
799+
800+
if (algorithmOid.Equals(X9ObjectIdentifiers.IdDsa))
801+
{
802+
var parameters = privateKeyInfo.PrivateKeyAlgorithm.Parameters.GetDerEncoded();
803+
var parametersReader = new AsnReader(parameters, AsnEncodingRules.BER);
804+
var sequenceReader = parametersReader.ReadSequence();
805+
parametersReader.ThrowIfNotEmpty();
806+
807+
var p = sequenceReader.ReadInteger();
808+
var q = sequenceReader.ReadInteger();
809+
var g = sequenceReader.ReadInteger();
810+
sequenceReader.ThrowIfNotEmpty();
811+
812+
var keyReader = new AsnReader(key, AsnEncodingRules.BER);
813+
var x = keyReader.ReadInteger();
814+
keyReader.ThrowIfNotEmpty();
815+
816+
var y = BigInteger.ModPow(g, x, p);
817+
818+
return new DsaKey(p, q, g, y, x);
819+
}
820+
821+
if (algorithmOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
822+
{
823+
var parameters = privateKeyInfo.PrivateKeyAlgorithm.Parameters.GetDerEncoded();
824+
var parametersReader = new AsnReader(parameters, AsnEncodingRules.DER);
825+
var curve = parametersReader.ReadObjectIdentifier();
826+
parametersReader.ThrowIfNotEmpty();
827+
828+
var privateKeyReader = new AsnReader(key, AsnEncodingRules.DER);
829+
var sequenceReader = privateKeyReader.ReadSequence();
830+
privateKeyReader.ThrowIfNotEmpty();
831+
832+
var version = sequenceReader.ReadInteger();
833+
if (version != BigInteger.One)
834+
{
835+
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "EC version '{0}' is not supported.", version));
836+
}
837+
838+
var privatekey = sequenceReader.ReadOctetString();
839+
840+
var publicKeyReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1, isConstructed: true));
841+
var publickey = publicKeyReader.ReadBitString(out _);
842+
publicKeyReader.ThrowIfNotEmpty();
843+
844+
sequenceReader.ThrowIfNotEmpty();
845+
846+
return new EcdsaKey(curve, publickey, privatekey.TrimLeadingZeros());
847+
}
848+
849+
if (algorithmOid.Equals(EdECObjectIdentifiers.id_Ed25519))
850+
{
851+
return new ED25519Key(key);
852+
}
853+
854+
throw new SshException(string.Format(CultureInfo.InvariantCulture, "Private key algorithm \"{0}\" is not supported.", algorithmOid));
855+
}
856+
715857
/// <summary>
716858
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
717859
/// </summary>

src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public EcdsaKey(SshKeyData publicKeyData)
204204
/// <summary>
205205
/// Initializes a new instance of the <see cref="EcdsaKey"/> class.
206206
/// </summary>
207-
/// <param name="curve">The curve name.</param>
207+
/// <param name="curve">The curve name or oid.</param>
208208
/// <param name="publickey">Value of publickey.</param>
209209
/// <param name="privatekey">Value of privatekey.</param>
210210
public EcdsaKey(string curve, byte[] publickey, byte[] privatekey)
@@ -266,24 +266,27 @@ private static Impl Import(string curve_oid, byte[] publickey, byte[]? privateke
266266
#endif
267267
}
268268

269-
private static string GetCurveOid(string curve_s)
269+
private static string GetCurveOid(string curve)
270270
{
271-
if (string.Equals(curve_s, "nistp256", StringComparison.OrdinalIgnoreCase))
271+
if (string.Equals(curve, "nistp256", StringComparison.OrdinalIgnoreCase) ||
272+
string.Equals(curve, ECDSA_P256_OID_VALUE))
272273
{
273274
return ECDSA_P256_OID_VALUE;
274275
}
275276

276-
if (string.Equals(curve_s, "nistp384", StringComparison.OrdinalIgnoreCase))
277+
if (string.Equals(curve, "nistp384", StringComparison.OrdinalIgnoreCase) ||
278+
string.Equals(curve, ECDSA_P384_OID_VALUE))
277279
{
278280
return ECDSA_P384_OID_VALUE;
279281
}
280282

281-
if (string.Equals(curve_s, "nistp521", StringComparison.OrdinalIgnoreCase))
283+
if (string.Equals(curve, "nistp521", StringComparison.OrdinalIgnoreCase) ||
284+
string.Equals(curve, ECDSA_P521_OID_VALUE))
282285
{
283286
return ECDSA_P521_OID_VALUE;
284287
}
285288

286-
throw new SshException("Unexpected Curve Name: " + curve_s);
289+
throw new SshException("Unexpected Curve: " + curve);
287290
}
288291

289292
/// <summary>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-----BEGIN ENCRYPTED PRIVATE KEY-----
2+
MIIBrTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIjn9BgD9X0loCAggA
3+
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBB3Zthr23nQDulzKryFEUTFBIIB
4+
UDW8/IR0K5DRScH4Cl7HOoK20aR+TmUOGczE027RL++iosgk5rYUpIKn0pxIKM0U
5+
StFGTqLz3G+bEh/Bm2Vt03Qv0Q2QZoX2e1Vktt32X2cLBNzGWfEpLuCD4vG8QDRW
6+
uGkE1NHxJKQTJWQt/gwGituyhMThGoE3ZcuqeLmRlhUSgRccO6WJ2HkNOW7TM5RB
7+
QbeBXmYB1H5S3FjpRAvd2p9dEzDsyquQaltFM4kekIxGjwiw5WSd+KsCGXFLa2Y2
8+
OXvcjRIIqGBJr+xvEVA86TNTfad+sKGqGUFszRmnGXA+VxEZju2OCpVhxTLEMX4Q
9+
2vYz9i8jE78tpx7C6PTKoJe5FTdlTatvWvYD5cvcbazPUjuZbraI9ha4XvNtERGC
10+
J0voz/7yeuNkW1ofxTUOu+snGhySC4AXkC44eZG4wUPfuQAswP8dFiQi2BthgVyP
11+
kA==
12+
-----END ENCRYPTED PRIVATE KEY-----

test/Data/Key.DSA.PKCS8.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBALVl3fae2O4qwsAK95SUShX0KMUN
3+
P+yl/uT3lGH9T/ZptnHSlrTxnTWXCl0g91KEeCaEnDDhLxm4aCv1Ag4B/yvcM4u3
4+
4qkmaNLy2LiAxiqdobZcNG61Pqwqd5IDkp38LBsn8tmb12xu9NalpUfOiSEB1cyC
5+
r4zFZMrm0wtdyJQVAhUArvojZKn/2DgGI2Kx0ghxZlgHxGECgYAOVJ434UAR3Hn6
6+
lA5nWNfFOuUVH3W7nJaP0FQJiIPx7GUbdxO9qtDNTbWkWL3c9qx5+B7Ole4xM7cv
7+
yXPrNQUYDHCFlS+Ue2x3IeJrkdfZkH9ePP25y5A0J4/c+8XXvQaj4zA5nfw13oy5
8+
Ptyd7d3Kq5tEDM8KiVdIhwkXjUA3PQQWAhQYRjs5PgIpnqG/euBPPh7EDZcnXg==
9+
-----END PRIVATE KEY-----
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-----BEGIN ENCRYPTED PRIVATE KEY-----
2+
MIHsMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAithDR1n5wCYQICCAAw
3+
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEMSzAQ3FSZ5hQHbmb7K9aB0EgZCS
4+
RVfVmMp1SBllrUMvdMEz5Zwvthaa1/M3Mc6MEVEzgROEXY3X+ywECU9q18aIOct+
5+
m5bmFcRcwoxo/hj6fsnmeH567KRfnN4Al219azq5ccwTr68y8tasYsZHOFCkn3ve
6+
Hkzu0+gylHZGWqo5TWif9O9DrII/KszsoX86jJxhORwqCnxMmKQQ/gGvexpAYJA=
7+
-----END ENCRYPTED PRIVATE KEY-----

test/Data/Key.ECDSA.PKCS8.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgR2poUqAkEiJtWPJS
3+
HW/tjfkvAhAmuhx1NpgUvCXuIHShRANCAARAPkw7+f3KpINOzPDNWkCkvHlJAV5w
4+
Tll8OSDGpV0dB5ybUEA+jNnh4oY2EqfvaFPv2YuWn0ddf6g0Ry5VPzcf
5+
-----END PRIVATE KEY-----
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-----BEGIN ENCRYPTED PRIVATE KEY-----
2+
MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAhiAnoQd2VMZwICCAAw
3+
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEENed/l3AFuDblxDnswMZXDcEQIpo
4+
fCVdEbDerN0Rrh9i+Ymu+qpEqGlc6jycwR3rPtyL9jy0k5kauBxRn3Z5uCSlGzJL
5+
JXxlMR+DWG6QDJdxrHI=
6+
-----END ENCRYPTED PRIVATE KEY-----

0 commit comments

Comments
 (0)