2012-04-01 33 views
8

Soy nuevo en paramiko, ¿alguna idea de cómo puedo usar la función paramiko.RSAKey.from_private_key()?¿Cómo se usa paramiko.RSAKey.from_private_key()?

Sé que hay un from_private_key_file(), pero estoy interesado en usar una función para analizar una clave privada (como a continuación) y usar esa clave privada para SSHClient.

clave privada (muestra)

-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKCAIEAmfgmlY95SHXhCeBNdkhSrsG4JVbqyew845yoZRX3wcS2/doz\niVQxgx0aiOwLi+/Rnkb3PLUIwoxb/LoD/W0YMS6/NSUMt+LdH+zsjeNF2iq4rDzU\nwDSqi27q/8u/egrK7H+9HNKEVXb/87utAAm3VTM9KqKaK3VuVFrNrnsDSuECAwEA\nAQKCAIBZn3y2KiGq8BLiMNJmO4sFdnW+Jm3cw8pdo17SGItzGxJ5iX3ePkfjzhkY\nAm5mMl6OBzj6+VX0CMeywIR6C/q8HwDYSmZcuU5v76/DoW5bI6xkPrroqEz6aRE5\nyN+2hf65RD3eoPATsdrP/kxiKjZg9uG9LhgIXyVwYFs1RcqewQJBAMCVJlEYXRio\neynUtyES9HNmUGUqHKmri1FZfO56/mFdG5ZXsKE48qURCAGVxI+goGQ4vtJIXB2J\nyTEr+5qYtE0CQQDMq9/iigk+XDOa9xGCbwxbLGdPawaEivezMVdPqVzH971L6kZ8\nhEnev1DqujgGCyR+QYPW1ZCXH05FY9CqWwrlAkATzYJyJlI0XebER2ZJVVyjnSq5\nLFpkLAqYY95P23/a3SsgC4ZTHbr9tEGhgBgFONwlUhx1HRGzy95PWxl1LSylAkBk\nwP93v8gJIM5urM27zfrhLxy0ZdVRji+d0N5QYuk/r19KbcvBJEZRFxE4W++UWgve\n81V5fqytGEYptpdUJXlZAkEArxZDiT1HXXGciIgzZbh53McogPCGHiKOOPSjpM41\npneDFVvwgezCWoDauxNDzu7Nl55qPJsmvfKZ+SKvCajrhQw==\n-----END RSA PRIVATE KEY-----\n 

Código quería correr:

import paramiko 
ssh = paramiko.SSHClient() 
# how do I pass in the private_key, when my private_key (shown above) is in string? 
mykey = paramiko.RSAKey.from_private_key(private_key) 
ssh.connect('192.168.1.2', username = 'vinod', pkey = mykey) 

Muchas gracias.

+0

Tienes una solución para este fin? – zengr

Respuesta

4

from_private_key() aparentemente toma un objeto de archivo:

from_private_key (CLS, file_obj, contraseña = None)

Crear un objeto clave mediante la lectura de una clave privada de un archivo (o archivo similar) de objetos . Si la clave privada está encriptada y la contraseña no es Ninguna, la contraseña dada se usará para descifrar la clave (de lo contrario, se lanza PasswordRequiredException).

Parámetros:

file_obj (archivo) - El archivo a leer desde contraseña (str) - una contraseña opcional para utilizar para descifrar la clave, si está encriptado

Devuelve: PKey

un nuevo objeto clave basada en la clave privada dada

eleva:

IOError - si hubo un error leer la clave

PasswordRequiredException - si el archivo de clave privada está encriptada, y la contraseña es Ninguno

SSHException - si el archivo de la clave no es válida

Así que para darle de comer una tecla como una cadena que pueda utilizar StringIO, algo así como:

private_key = StringIO.StringIO(key_string) 
mykey = paramiko.RSAKey.from_private_key(private_key) 

no he probado esto, sin embargo. Método

+1

No funciona. 'key_string' es la clave privada como cadena. Obtengo esta excepción: 'SSHException: no es un archivo de clave privada de RSA válido' – zengr

4

de Lev trabajado para mí:

>>> import paramiko 
>>> f = open('/path/to/key.pem','r') 
>>> s = f.read() 
>>> import StringIO 
>>> keyfile = StringIO.StringIO(s) 
>>> mykey = paramiko.RSAKey.from_private_key(keyfile) 
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
>>> ssh.connect('myserver.compute-1.amazonaws.com', username='ubuntu', pkey=mykey) 
>>> stdin, stdout, stderr = ssh.exec_command('uptime') 
>>> stdout.readlines() 
[' 19:21:10 up 24 days, 42 min, 1 user, load average: 0.14, 0.06, 0.05\n'] 
+1

Aún más fácil con' paramiko.RSAKey.from_private_key_file (filename) ', consulte http://docs.paramiko.org/en/1.15/api/keys. html # paramiko.pkey.PKey.from_private_key_file – ezdazuzena

+0

@ezdazuzena, a veces solo tienes una cadena en la memoria, no un archivo. – odiszapc

+0

para python3, use io en lugar de StringIO –

1

Aquí es donde 'pato escribiendo' viene muy bien - que no tiene que ser un pato (= archivo), sólo tiene que comportarse como tal.

Un poco de experimentación muestra que, cualquier objeto que tenga un método readlines() válido está bien.

fingí con:

def myfakefile(keystring): 
    myfakefile.readlines=lambda: keystring.split("\n") 
    return myfakefile 

mykey = paramiko.RSAKey.from_private_key(myfakefile(keystring)) 

Esto es increíblemente hacky, pero funciona.

Lo que hace es, cuando llama a myfakefile (cadena de caracteres), crea myfakefile.readlines, que devuelve los contenidos (divididos) de las cadenas de teclas.

Luego, devuelve la función.

La misma función se pasa a from_private_key. from_private_key, creyendo que es un archivo, llama a myfakefile.readlines(). Esto llama a la función recién creada (lambda), que devuelve el tipo de cosas que esperaría de file.readlines() - o, lo suficientemente cerca, de todos modos.

Tenga en cuenta que, salvando los resultados no funcionará como se esperaba:

k1=myfakefile(keystring1) 
k2=myfakefile(keystring2) 

# This will return keystring2, not keystring1! 
paramkiko.RSAKey.from_private_keyfile(k1.readlines()) 

Hay métodos más robustos de conseguir que esto funcione como debe ser, pero no vale la pena el esfuerzo - sólo tiene que utilizar StringIO si sus necesidades son más complicado.

+0

mientras me gusta este estilo, no estoy seguro de que recomiende esto (paramiko _may_ puede cambiar su API). –

-1

muy vieja pregunta, pero en caso de que ayuda alguna alma desafortunada: mi sol'n a este problema fue generar una nueva clave con las opciones predeterminadas, utilizando

ssh-keygen -t rsa

Mi llave anterior se generó usando

ssh-keygen -t rsa -b 4096 -a 100

cuales se quejaron de paramiko como lo hizo para OP.

+0

Se quejó Paramiko se debió a que el distintivo -o guardó la clave en el formato OpenSSH, y * no * espera el paramiko de formato RSA. Si suelta el indicador -o al generar la clave, paramiko debería trabajar con la clave resultante. – KiwiMartin

0

Esto debe hacerlo:

import io 
import paramiko 

private_key_file = io.StringIO() 
private_key_file.write('-----BEGIN RSA PRIVATE KEY-----\nlskjdflk\n...\n-----END RSA PRIVATE KEY-----\n') 
private_key_file.seek(0) 
private_key = paramiko.RSAKey.from_private_key(private_key_file)