SSH.NET
SSH.NET copied to clipboard
Failure parsing private key with PEM format generated by OpenSSH 9.9p1 (macOS 15.4)
The OpenSSH version that macOS 15.4 ships (9.9p1) generates PEM private keys including some extra metadata that makes SSH.NET fail to parse it.
Steps to reproduce it:
- Generate a private key on macOS 15.4 using the following command:
ssh-keygen -t ecdsa -b 521 -m PEM -f ./pkey.pem -q
- Add the following code to a .NET app:
var pkey = new PrivateKeyFile("<path to pkey.pem>");
- Run the app and you will get the following exception:
Exception has occurred: CLR/System.Formats.Asn1.AsnContentException
An unhandled exception of type 'System.Formats.Asn1.AsnContentException' occurred in System.Formats.Asn1.dll: 'The provided data is tagged with 'Universal' class value '16', but it should have been 'Universal' class value '6'.'
at System.Formats.Asn1.AsnDecoder.CheckExpectedTag(Asn1Tag tag, Asn1Tag expectedTag, UniversalTagNumber tagNumber)
at System.Formats.Asn1.AsnDecoder.GetPrimitiveContentSpan(ReadOnlySpan`1 source, AsnEncodingRules ruleSet, Asn1Tag expectedTag, UniversalTagNumber tagNumber, Int32& bytesConsumed)
at System.Formats.Asn1.AsnDecoder.ReadObjectIdentifier(ReadOnlySpan`1 source, AsnEncodingRules ruleSet, Int32& bytesConsumed, Nullable`1 expectedTag)
at System.Formats.Asn1.AsnReader.ReadObjectIdentifier(Nullable`1 expectedTag)
at Renci.SshNet.Security.EcdsaKey..ctor(Byte[] data)
at Renci.SshNet.PrivateKeyFile.Open(Stream privateKey, String passPhrase)
at Renci.SshNet.PrivateKeyFile..ctor(String fileName, String passPhrase, String certificateFileName)
at Renci.SshNet.PrivateKeyFile..ctor(String fileName)
at Program.<Main>$(String[] args) in
If you compare the result of running the same ssh-keygen command in macOS 15.4 (OpenSSH 9.9p1) and macOS 14.6.1 (OpenSHH 9.7p1), you'll see the newer version generates a lot of extra content that seems to be the culprit of the parsing content exception.