2

This is related to Converting keys between openssl and openssh .

I have private keys generated by openssl that I want to use with SSH for connection authentication. I have no issue using ssh-keygen to generate a public key. However, I'm now trying to use CA certificate signing as I'm dealing with over 100 machines that need to connect via SSH.

If I try to do ssh-keygen -s ca.key -I dev1 dev1.key on my openssl generated key I get a message saying 'do_ca_sign: unable to open "dev1.key"'. I noticed that my openssl private keys are all 1675 bytes and the private keys generated by ssh-keygen are all 1679 bytes. Do I need to do some sort of conversion on the openssl keys before being able to sign them with the ca.key? Strangely ssh-keygen has no problem reading the same private key to generate a public key so I'm lost as to what to do.

2 Answers 2

2

TL/DR: ssh-keygen only signs public keys. However, it tries to recover from being passed a private key by looking for an appropriately named public key automatically and gives no warning messages.

Unfortunately, SSH keys do not implement trusted third party as certificates do. SSH keys are quite basic, they are just "keys" as the name imply, without all the bell and whistles you may find in certificates (certificates being actually a key wrapped in a container adding supplementary information, and the CA signature is part of this container).

Would you need to find a way to handle SSH keys on a large number of hosts, you may be interested in this thread, where a solution is proposed to use MonkeySphere which relies on OpenPGP web of trust to add trusted third party concepts including to OpenSSH.

Edit: As appeared in the discussion below, openSSH added a specific feature implementing signing a public key using a third party CA key.

The command given in the question, "ssh-keygen -s ca.key -I dev1 dev1.key" does not work because, as stated in ssh-keygen manpage, dev1.key must be a public key.

However, when the file given as parameter is not a valid public key, before giving up ssh-keygen will check for the existence of a file named {filename}.pub which may contain the expected public key.

In the case of keys generated using ssh-keygen, this *.pub file is automatically generated, so when giving the private key file as parameter ssh-keygen will transparently fallback on the public key file.

However, key files manually generated from SSL certificates did not respect the same convention (the file dev1.key did not have its dev1.key.pub counterpart), and that's what it was failing in this case.

Edit 2: Checking this behavior is as simple as launching the command below

strace ssh-keygen -s ca.key -I dev1 dev1

The behavior I describe appear here:

# First ssh-keygen try to open the file given as parameter:
...
open("dev1", O_RDONLY)                  = 3
fstat(3, {st_mode=S_IFREG|0600, st_size=1671, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f15ec1c0000

# Then it reads its content:
read(3, "-----BEGIN RSA PRIVATE KEY-----\n"..., 4096) = 1671

# Seeing it is not a public key, it closes it:
close(3)                                = 0
munmap(0x7f15ec1c0000, 4096)            = 0

# Then he checks if a file with extension .pub exists:
open("dev1.pub", O_RDONLY)              = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=405, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f15ec1c0000

# If it exists, it reads it content too to check if it is a valid public key file:
read(3, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB"..., 4096) = 405

# Yes it is, so now having read its content, it closes it and proceeds with
# creating the signed version of this public key (file 'dev1-cert.pub'):
close(3)                                = 0
munmap(0x7f15ec1c0000, 4096)            = 0
open("dev1-cert.pub", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
...
11
  • "ssh-keygen -s ca.key -I dev1 dev1.key " creates a private key signed by the CA. You can then use the CA public key on the server for authentication. My problem is just using private keys not generated with ssh-keygen. Jan 24, 2015 at 13:15
  • @TimTisdall Indeed feature specific to openSSH added in 2010 (OpenSSH 5.4). I get your error only when dev1.key does not exists or is not valid. Do you confirm it is a public key and not a private one? Would it be possible to get more information about how you generated it? A strace showing the last execution steps (starting from "open("dev1.key", O_RDONLY)") of ssh-keygen might also be usefull (it shows clearly if the file has been found, etc.). Jan 24, 2015 at 14:14
  • I'm pretty sure it has to be with the private key, that's what works when using a ssh-keygen created key pair. Yes, I noticed that too, the error message is pretty useless. I'll report back when I have a chance to do an strace. Jan 24, 2015 at 14:21
  • As specified in the manpage, under the "-s ca_key" option, "Certify (sign) a public key using the specified CA key.", I therefore confirms it signs the public key. Thanks to this, the user keeps the private key secret, and only has to provide the public key to the third party authority to sign it. Jan 24, 2015 at 14:26
  • strange... I converted the openssl private key into a public key and then was able to sign it properly. However, the program had no complaints signing the private key generated by ssh-keygen. Jan 24, 2015 at 21:30
2

Digital Ocean published a tutorial showing how ssh-keygen can be used to sign a user's public key with a CA certificate. Generate a CA with ssh-keygen (NOT with openssl)

ssh-keygen -f users_ca

/etc/ssh/sshd_config can be amended so that the public keys don't need distribution:

AuthorizedKeysFile /dev/null

As long as the CA certificate is present and configured:

TrustedUserCAKeys /etc/ssh/users_ca.pub

Configure AuthorizedKeysFile to another value to allow exceptions

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .