Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does SSH.NET accept only OpenSSH format of private key? If not, what are the restrictions?

The manual doesn't indicate such, but some Googling returns pages from the turn of the decade (such as this) suggesting that this at least used to be the case. We have code like this:

var privateKeyAuthenticationMethod =
    new PrivateKeyAuthenticationMethod(userName, new PrivateKeyFile(privateKeyLocation));
var connInfo =
    new ConnectionInfo(
        ftpSettings.HostAddress, ftpSettings.UserName, privateKeyAuthenticationMethod);
using (var client = new SftpClient(connInfo))
{
    client.Connect();
    client.UploadFile(memStreamData, destination);
}

This hooks into a private key that we have used successfully via SCP2 (Secure Copy 2 as detailed here) - it is 2048 DSA, which is listed as valid in the SSH.NET documentation. The key uses an ssh.com format like:

---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
Subject: <FID name>
Comment: "2048-bit dsa, <FID name>@<Server name>, Mon Apr 24 201\
 7 15:49:36 +0100"
<ENCRYPTED KEY>
---- END SSH2 ENCRYPTED PRIVATE KEY ----

However, there is a Regex within the private key handling portion of SSH.NET that fails to match our private key, and so throws an exception:

ERROR 2017-05-10 15:31:43 UTC [T: 474] – Invalid private key file.
ERROR 2017-05-10 15:31:43 UTC [T: 474] – at Renci.SshNet.PrivateKeyFile.Open(Stream privateKey, String passPhrase)

It does however match if we convert the key to OpenSSH format, but this is not necessarily something that we can use in production due to business constraints.

Does anyone know exactly what the restrictions are on Private Key format for SSH.NET please? We are not sure if this time if we need to abandon SSH.NET for some other SFTP wrapper library, write our own, or what.

like image 958
Gravyweg Avatar asked May 11 '17 12:05

Gravyweg


People also ask

What is the format of OpenSSH private key?

So, the OpenSSH private key format ultimately contains a private key encrypted with a non-standard version of PBKDF2 that uses bcrypt as its core hash function. The structure that contains the key is not ASN. 1, even though it's base64 encoded and wrapped between header and footer that are similar to the PEM ones.

What type of SSH key should I use?

Only three key sizes are supported: 256, 384, and 521 (sic!) bits. We would recommend always using it with 521 bits, since the keys are still small and probably more secure than the smaller keys (even though they should be safe as well). Most SSH clients now support this algorithm.

How does SSH work with keys?

An SSH key relies upon the use of two related keys, a public key and a private key, that together create a key pair that is used as the secure access credential. The private key is secret, known only to the user, and should be encrypted and stored safely.


1 Answers

As the in-code documentation for PrivateKeyFile type says:

Supports RSA and DSA private key in both OpenSSH and ssh.com format.


I have generated new ssh.com private key:

---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
Comment: "dsa-key-20170511"
P2/56wAAA4IAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA
AEbm9uZQAAA0QAAANAAAAAAAAACACOT7SBNaNYmT13gDCCFyE/3yEs6oVbmmGVM6dIesTC
iwY26oHL2JKNLh2gHYfwa9iwDESAH6CIUR+Jf19KXLyNMLQgsoEhfZRS35mDC0pyoYgD77
N2VXt7hkEYFYuJK459HmmoJ2DABdZ9Anb6twDwfY7XhRdLz2H44OOifd1qKjYd/qzsm9MQ
4qUDHYsJpfCly2DFjcFy915fPW4IrTguCRRv545B949iZD/9VcysVe5Cs5DKe1zQybgs2L
qRgMXVS8eHIx4ASNRP6Z9gllkPK2CqWMeLL7P0oR6fNuC8T02xy0CTNh9s041mB7zN5Sfy
kuTzqh6Wkj3t9Z9Fv8YxAAAH/iadRhuaJzO7c9oA4+Z/aPwcTQZQiyeZ0jzTzKUZsyOUiV
PDGxsAuBAcMapskELDdWy0n0S0im4HyxouQrQxqIHBtzucuD4YznIdsCCjs8S0NiBLXEE1
DYyiIpnAgpoC1j6b00L3LosaI2szOAp2fGB2dtXizX6fIkUZssNZthEbpOKGvItor7JUv8
urcbl56S9B+mdyTm/a+zKP+Q5rC9mjd/N6X+9+pZxPoSfEzgclUOLxC+zJigpUEZ9UcqGR
eCT881CKmd0HRrVG3uzgVvsnnzX7wyTnOqg2CXuESB3NvvlzM2Vsa3UuBU1AjBj1++0h5Q
VJ83MZmlp2seG0m3MAAACg22bQYT6jD8GG9XaeoHXwnaPCB8kAAAgAh5QuiehV7IZN9G0R
V4t/sdnhA8M5X7YXw9iQUu08TYmPomZATI/7OlUYySPsjuf5IbRWSKXVP1x2Rku8gJQnAI
lbS6jhxHjx61fwD4jctaCZdI1MzXgW/PtIv3Sc6JyJdnD1dqKieUuRG6PhTFqoG3F1YHyy
VydaIhB1vKi90sTJ5AXXEZG81Q7yRBItJqr46XBz0W4CqQS6aguzzO9ZEdcadJGfDF6Bp8
Ymxzf58lYNrCJem4p7axM7P/9HaNW4xzRb5N0hyBYjFXAFa/mo2jARWHQTGeQy7KbdfUKE
vkxd96qK3InQHijWelnKAT5KgFaM9P1AEsgLnNRlQdn/fwAAAJ4qvy/nqPvqBwotQLLE0I
M9rbFIdA==
---- END SSH2 ENCRYPTED PRIVATE KEY ----

The SSH.NET 2016.0.0 PrivateKeyFile can load it without any problem.


One thing with your key, that the PrivateKeyFile cannot handle, is the Subject: header. Remove it.

If you need the key file intact, just remove it on-the-fly, while reading:

string key = File.ReadAllText(@"C:\path\key");
Regex removeSubjectRegex = new Regex("Subject:.*[\r\n]+", RegexOptions.IgnoreCase);
key = removeSubjectRegex.Replace(key, "");
MemoryStream buf = new MemoryStream(Encoding.UTF8.GetBytes(key));
PrivateKeyFile privateKeyFile = new PrivateKeyFile(buf);
like image 122
Martin Prikryl Avatar answered Oct 17 '22 13:10

Martin Prikryl