| switch(keyName) |
| { |
| case"RSA": |
| _key=newRsaKey(decryptedData); |
| HostKey=newKeyHostAlgorithm("ssh-rsa",_key); |
| break; |
| case"DSA": |
| _key=newDsaKey(decryptedData); |
| HostKey=newKeyHostAlgorithm("ssh-dss",_key); |
| break; |
| case"SSH2 ENCRYPTED": |
| varreader=newSshDataReader(decryptedData); |
| varmagicNumber=reader.ReadUInt32(); |
| if(magicNumber!=0x3f6ff9eb) |
| { |
| thrownewSshException("Invalid SSH2 private key."); |
| } |
| |
| reader.ReadUInt32();// Read total bytes length including magic number |
| varkeyType=reader.ReadString(SshData.Ascii); |
| varssh2CipherName=reader.ReadString(SshData.Ascii); |
| varblobSize=(int)reader.ReadUInt32(); |
| |
| byte[]keyData; |
| if(ssh2CipherName=="none") |
| { |
| keyData=reader.ReadBytes(blobSize); |
| } |
| elseif(ssh2CipherName=="3des-cbc") |
| { |
| if(string.IsNullOrEmpty(passPhrase)) |
| thrownewSshPassPhraseNullOrEmptyException("Private key is encrypted but passphrase is empty."); |
| |
| varkey=GetCipherKey(passPhrase,192/8); |
| varssh2Сipher=newTripleDesCipher(key,newCbcCipherMode(newbyte[8]),newPKCS7Padding()); |
| keyData=ssh2Сipher.Decrypt(reader.ReadBytes(blobSize)); |
| } |
| else |
| { |
| thrownewSshException(string.Format("Cipher method '{0}' is not supported.",cipherName)); |
| } |
| |
| // TODO: Create two specific data types to avoid using SshDataReader class |
| |
| reader=newSshDataReader(keyData); |
| |
| vardecryptedLength=reader.ReadUInt32(); |
| |
| if(decryptedLength>blobSize-4) |
| thrownewSshException("Invalid passphrase."); |
| |
| if(keyType=="if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}") |
| { |
| varexponent=reader.ReadBigIntWithBits();//e |
| vard=reader.ReadBigIntWithBits();//d |
| varmodulus=reader.ReadBigIntWithBits();//n |
| varinverseQ=reader.ReadBigIntWithBits();//u |
| varq=reader.ReadBigIntWithBits();//p |
| varp=reader.ReadBigIntWithBits();//q |
| _key=newRsaKey(modulus,exponent,d,p,q,inverseQ); |
| HostKey=newKeyHostAlgorithm("ssh-rsa",_key); |
| } |
| elseif(keyType=="dl-modp{sign{dsa-nist-sha1},dh{plain}}") |
| { |
| varzero=reader.ReadUInt32(); |
| if(zero!=0) |
| { |
| thrownewSshException("Invalid private key"); |
| } |
| varp=reader.ReadBigIntWithBits(); |
| varg=reader.ReadBigIntWithBits(); |
| varq=reader.ReadBigIntWithBits(); |
| vary=reader.ReadBigIntWithBits(); |
| varx=reader.ReadBigIntWithBits(); |
| _key=newDsaKey(p,q,g,y,x); |
| HostKey=newKeyHostAlgorithm("ssh-dss",_key); |
| } |
| else |
| { |
| thrownewNotSupportedException(string.Format("Key type '{0}' is not supported.",keyType)); |
| } |
| break; |
| default: |
| thrownewNotSupportedException(string.Format(CultureInfo.CurrentCulture,"Key '{0}' is not supported.",keyName)); |
A NotSupportedException is thrown when generating SSH keys with the "ssh-keygen" command on a Mac with macOS Mojave 10.14.1. With lower versions it's working fine.
Exception:
System.NotSupportedException: Key 'OPENSSH' is not supported.
at Renci.SshNet.PrivateKeyFile.Open(Stream privateKey, String passPhrase)
at Renci.SshNet.PrivateKeyFile..ctor(String fileName, String passPhrase)
Inspecting the generated private key I can see that the header starts with:
"-----BEGIN OPENSSH PRIVATE KEY-----"
Also, If I inspect a private key generated in a Mac with a lower macOS version, I can see something like:
"-----BEGIN RSA PRIVATE KEY-----"
The following code in this repo tries to match a Regex to detect they key name and act based on it. For this reason, It doesn't recognize "OPENSSH" as a valid private key name and it fails:
SSH.NET/src/Renci.SshNet/PrivateKeyFile.cs
Lines 190 to 273 in bd01d97
Thanks.