2

I need to generate an RSA keypair for use with SFTP authentication. SFTP uses OpenSSH, and according to its IETF specification, keys should only be generated by ssh-keygen. https://www.openssh.com/specs.html

However, for my current project, I cannot rely on an external program like ssh-keygen, even if executed through something like python's subprocess module. This has to do with the details of the deployment environment. Anyway, for some reason the keys I am generating with python's cryptography module, although they appear correct, are rejected during SFTP login.

I don't know what makes the ssh-keygen keys so special. I suspect it either has to do with parameters like the key size/length or the public exponent, or else possibly it's due to a character encoding issue.

Here is the code that is generating the keys

from cryptography.hazmat.primitives import serialization as crypto_serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend as crypto_default_backend

key = rsa.generate_private_key(
    backend=crypto_default_backend(), public_exponent=65537, key_size=2048)
private_key = key.private_bytes(
    crypto_serialization.Encoding.PEM, crypto_serialization.PrivateFormat.PKCS8, crypto_serialization.NoEncryption()).decode("utf-8")
public_key = key.public_key().public_bytes(
    crypto_serialization.Encoding.OpenSSH, crypto_serialization.PublicFormat.OpenSSH).decode("utf-8")
print(public_key)
print(private_key)

Below are keys generated by ssh-keygen that sftp accepts.

Public key:

(I modified the user@machine_name part, but I highly doubt this is relevant, since I am actually stripping this part out when I deploy the public key to the sftp server)

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWe1fmzvKHYu90YbGiDVD/k+Jj6OgQLUuleTIkAiljrN+Z6RTF9xK6bk5uEquB5TBWvl/i9kh8blCjkxnKI8ivvBZiX6ubuRraEtkmRR+/UmxHehKwE40eAtbFjY6q69PpNBg+iM7nXrTHK1vmD5VY8KsflfKBmS628V0QxxgQTdi/irb4AZLBqR7lAnanB15envtMBxoesoA6Duaj47TftzDP2j8iX7Jgj+WZqB85aqggbxUfV0kDVj9YbSuZk9ccA3udRlMpH2k1aiMemF0zB2jHXHPHTE+0sIoX0J331+yzWR+iJXwZeEdRREmeTc8FJN2/Rq1lLH87NPkB4uhH user@machine_name

Private key:

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1ntX5s7yh2LvdGGxog1Q/5PiY+joEC1LpXkyJAIpY6zfmekU
xfcSum5ObhKrgeUwVr5f4vZIfG5Qo5MZyiPIr7wWYl+rm7ka2hLZJkUfv1JsR3oS
sBONHgLWxY2OquvT6TQYPojO5160xytb5g+VWPCrH5XygZkutvFdEMcYEE3Yv4q2
+AGSwake5QJ2pwdeXp77TAcaHrKAOg7mo+O037cwz9o/Il+yYI/lmagfOWqoIG8V
H1dJA1Y/WG0rmZPXHAN7nUZTKR9pNWojHphdMwdox1xzx0xPtLCKF9Cd99fss1kf
oiV8GXhHUURJnk3PBSTdv0atZSx/OzT5AeLoRwIDAQABAoIBADX/z924dK9JZWgz
wHlASQhPv0vQM7z+6nC61rjiInGJ8LHbUPOWhQyTAQQNh0io30a3n4SQ5ScOzxaf
znpqD/jOrgQOejI2pGALJsjP1nJg2goU3eeexIStykzqmuTFgxDPoNr9rrnpyjHq
5LRDcCJ4VV0ab3fZjT1Z/0heF9zihnnZ1eQ/4DCgkSQe9IVVmyoTCRAL57DE4JVa
XSq7rWjnFO9fFUFH2HaWUvZqZJcwStr4UrgxhE+x57b5ymhwcf+PQNyrGFSDHdFu
calbCZKyriTe3/CGyKy0TuHbjYd89cE/6kJ8UBuBdr40ttRKj50l3h2PDoYLgP3d
N+HPSyECgYEA9KH7DmRI5iFOul/nImy3MXkaruVehgXmFytCzrysNDNp66o+8dZ4
PBdZDmMhFLIwM/v7a1RLnEHOkF0oIXLWJaVaWqT64RipvtUvYie1zSTbviLLMaJT
FvrH9Xwx82HobkOyrLc26m/gSktKT2OmzJmt+YhByqsPim5L8u+QsAUCgYEA4HK0
F5I0WrLV3abN3g9VkSEfdp3QvF0eTzS7i9C83mAlVizt9PqGjvLIWUfSRiTZPCzX
vaT/sHX3xi2znDUYQ43aFouAzVyN9Qa76nxtuB6c2iBM6sW69Mcct8M9HdjcPF6O
v9XqXuZTn/AD9AHoTHZtGOnMKTX0YjEqeHbfRNsCgYAKDWHonHxWYIYAqJIx2u/I
K6bKCwjQTwu+ZfuvzRbyai5vDabafyqfpYH2UmJ4nD3Y1QDmzybwO9AGJJ3Sigp8
r4e/88mPWFkZS19QFDunO12AOaPJ3Va2ugVfdAQFcT+A0G1WJY0vIvu/ccqS6pBf
Fe2NNGknr9HKqW+bgvaaFQKBgQC7gVfOcUfnlYtxVo6ZurnDOqasU380PZ66kNU1
IrcGF9BZQ8OvazPKbCzP2V5jVxlcWiIJvrQU2RibqUZpcznIBdNyDi0WYwH89xk5
9aU7sedbmqxnXbSoFUd6hVKjgq3KiTw8KxtXGJg3/y1uRcGpTy4pJ/h1XSvCdEyE
wtoXDQKBgQC8RjCF3ZcZYIIii10K0BHX4YSiRC3PLi7rUQ9jVZN4FGwBB+NQzwSe
7iIW4lqUDZ6SKDwkNKi5vdnx2BBBadJO74vcqWxdanBk0SbEsJZDFVb2bGvjOVzH
CLhCavojqtFNMCFQTge9P6wff+qegY1RzTEkht3YiiWAGkFkDVp5gg==
-----END RSA PRIVATE KEY-----

Below is output of my program

Public key:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDr0tbRIlabQr6xPudI3Gz9qN7hIeKhMdrxiKzXsgfBElRF6htfUebwFTcmRrPeb0mN+wCdcrnAF+iG+cYvpjhX6mQa+rBV79kiUZJg3n/BfjiMBko9q6QDrpOfNdKElnGVqBcTFSZKyzNfGpOTcpzCxXd76IyUx1MuY2A4MUC/TVBNpJnrEqvJjaAAbtTWDXYmzmApL3m308CH+SV2NKE5dzHNX+NvFeZ2Xlcv5ZRGB6jiUV+HI3QFPeaLJ+xneucc0rCrjF22RHvBFovnInFnIDXdadqsElxAKYviygpZL6ekJJETJhZjGzDNJh0b30OiZS493CDmd7Qb97MfN95/

Private key:

-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDr0tbRIlabQr6x
PudI3Gz9qN7hIeKhMdrxiKzXsgfBElRF6htfUebwFTcmRrPeb0mN+wCdcrnAF+iG
+cYvpjhX6mQa+rBV79kiUZJg3n/BfjiMBko9q6QDrpOfNdKElnGVqBcTFSZKyzNf
GpOTcpzCxXd76IyUx1MuY2A4MUC/TVBNpJnrEqvJjaAAbtTWDXYmzmApL3m308CH
+SV2NKE5dzHNX+NvFeZ2Xlcv5ZRGB6jiUV+HI3QFPeaLJ+xneucc0rCrjF22RHvB
FovnInFnIDXdadqsElxAKYviygpZL6ekJJETJhZjGzDNJh0b30OiZS493CDmd7Qb
97MfN95/AgMBAAECggEAFJ5QjeR0sgp55cFcM3CiTuNO6VwvFmzneaq7gfhc2TKj
D6HSVtkwWdlhAwW3gEE2qyVA/oMjXno4qGR6QXxE/NrPedRlSn43+9op9DI/9Uj1
5LhAEXhKVNAUtBzelR0aPT1/FvoIaQ2vJieKs5+XuSfOtJS2heOPkES8Cu2zfYY3
/egSvYCCWoG12xYx7u67b0z4ZUV7a0sbLTov0+R3UAlI68hUy6z5Eu45QdZ83D9U
qO/JDeycSvOldpuV5kmRD0lTvsc0hDrlr0pA7yzf7/M+NI4r8cfXPpJZLK3Riott
GYS6YN4JmfO7D6nP2DjyrboDsVDy4TJkD/ZycMd/AQKBgQD8jmMAQFiJGoMlOqyC
YGxwOxL/qvFEQ2R1FDIywpDQnsK/Jrln6zgR88MWyuJyM+7MHgF5BP9u8hS3WQ0U
DF2sGBfFQNJUWJUKAtHpfA/qsep1PX6lr9mWZYFEIEugDZDRLVVDFvLG7tk8fauD
bvmMexy+0uT9dTsmx3GaLm9avwKBgQDvCgr51MHTj1E7Ynv0aI20ySI8vZnEHnPU
r36GIfqz5i67KLG3HTV0Awo4njXa6W6w+Kdg78saRXhVbZFlRfYIfsVT9OpRxKXM
QDElK0gtrJRIRgLz7/1lVUUE4Hj0a76p7GhfhES2qKYqIPnF/lpfMt44DE+ARmEK
ra03cecsQQKBgCGmZxJ1gFZkLe0b8Dg+2LPraxCdmh/aStw+oKGawujI/nGxmyp5
cLMTo3658Yn92Wdg6BlTzSTfJFt5hgCR1TlEzIX/qQaL9u+qiIVvfj9rDS4pz2IM
GBWt2JdXJjxhElaMj7uspxRSZqdkpyGP+7f3/1B9kP0kTYlRMZW1cijJAoGAMRvH
FXx4NZaEAcdB3/x64GFR/1iUdo4rDc7gF35zmvH3N8wsdooxqRvWxbr7JXY/n2v2
NxwMheEvz50q+btdyHEC6TSvzwyvYz7s2c4Cjh+edxqrEKKFVIQoIdBcCRr5mL9Q
0g7CbyRGvvD3X43Z0yUIMkuVKa1L0n3L0FA+RgECgYArd7mvlJTIu6b2TZdQsTLt
5Ygqpkgz5ZcFX3fuiaJLFqpUnYYns7aBmHbotBKijEN7ags7SMilMuXqY5+OraJG
+qoheN5EGgvgiT9KF6KBjZblUCUFak5SAS8F+/J5oIPNLzZmf+Q5CKncswBSBras
ka+XkZ5QzRm6hFZB7E7q6A==
-----END PRIVATE KEY-----
4
  • I don't know where you got the information in your first paragraph but it's mostly wrong. Why not just use whatever SSH library you are using generate the keys? Commented Jul 10, 2019 at 22:17
  • I got the information from that link Commented Jul 10, 2019 at 22:41
  • You misunderstood. Are you using Paramiko for SFTP? Commented Jul 10, 2019 at 22:46
  • No. I am using aws transfer sftp service Commented Jul 11, 2019 at 0:40

1 Answer 1

3

The header that is OpenSSH ssh-keygen using is the legacy PEM file:

-----BEGIN RSA PRIVATE KEY-----

The header your script created is the new PKCS#8 PEM file and they are not completely compatible if you are using some nonstandard tool to connect to the sftp.

-----BEGIN PRIVATE KEY-----

You can create the same legacy PEM format using the serialization.TraditionalOpenSSL argument to your private_bytes function.

Sign up to request clarification or add additional context in comments.

5 Comments

Great tip! I changed to private_key = key.private_bytes(crypto_serialization.Encoding.PEM, crypto_serialization.PrivateFormat.TraditionalOpenSSL, crypto_serialization.NoEncryption()).decode("utf-8") and output says RSA PRIVATE KEY but it's still not working. The private key file is actually a few characters shorter than the rsa-keygen file
Actually, my bad, it is working. Your solution fixed it, thanks!
FYI: This format is not a legacy format. This format is PKCS #1 and is widely used everywhere. PKCS #8 is another format with more options.
@JohnHanley that is nothing that would not make it legacy format as there is one that is widely accepted as a replacement in everything modern.
You are expressing your opinion as a fact. PKCS #1 is part of a family of standards and is by far the most popular format. In most use cases, PKCS #8 just wraps PKCS #1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.