2011-03-11 25 views
20

Estoy trabajando en una aplicación Ruby/Rack que necesita generar pares de claves SSH. Por mucho que me gustaría llamar al ssh-keygen desde la aplicación, no puedo porque está diseñado para ejecutarse en Heroku y no admiten llamar a ese comando.Generar pares de claves SSH (privado/público) sin ssh-keygen

he sido capaz de obtener las claves privadas/públicas RSA utilizando OpenSSL en la biblioteca estándar de Ruby haciendo lo siguiente:

key = OpenSSL::PKey::RSA.generate(2048) 
# => -----BEGIN RSA PRIVATE KEY----- .... 
key.public_key 
# => -----BEGIN RSA PUBLIC KEY----- .... 

Desafortunadamente una clave pública RSA y una clave pública SSH no es la misma cosa, a pesar de que se pueden generar a partir de la misma clave RSA. Una clave pública SSH se ve algo como lo siguiente:

ssh-rsa AAAAB3NzaC1yc2EAAAABIwA..... 

¿Es posible generar claves SSH o convertir las claves RSA a SSH en Ruby sin utilizar ssh-keygen?

Respuesta

15

resulta que esto era mucho más complicado de lo que pensaba. Terminé escribiendo el SSHKey gem para sacarlo (código fuente on GitHub). Las claves públicas SSH están codificadas de forma totalmente diferente a la clave pública RSA proporcionada. La codificación del tipo de datos para las claves SSH se define en la sección # 5 de RFC#4251.

1
key.public_key.to_pem 

El proceso completo, incluyendo el cifrado de clave está documentado aquí: http://stuff-things.net/2009/12/11/generating-rsa-key-pairs-in-ruby/

+0

OpenSSL :: PKey :: RSA # to_pem parece proporcionar solo una salida de cadena, no la convierte al formato de clave pública SSH. – bensie

+0

También intenté simplemente anteponer el "ssh-rsa" y anexar la sintaxis del comentario a la cadena, pero no es lo mismo y no se reconoce como una clave pública válida. – bensie

25

Se puede no haber sido el caso en que tuvo el problema, pero los net-ssh parches biblioteca OpenSSL::PKey::RSA y ::DSA con dos métodos:

#ssh_type - Devuelve "ssh-rsa" o "ssh-dss" según corresponda

y #to_blob - devuelve el clave pública en formato OpenSSH binary-blob. Si lo codifica en base64, es el formato que está buscando.

require 'net/ssh' 

key = OpenSSL::PKey::RSA.new 2048 

type = key.ssh_type 
data = [ key.to_blob ].pack('m0') 

openssh_format = "#{type} #{data}" 
+2

Esta es una solución realmente agradable y sucinta. – sethvargo

+0

nota, net/ssh es una gran joya y eso como parche de mono y demás. La respuesta de @Bensie es mucho más liviana –

Cuestiones relacionadas