2012-04-17 19 views
5

Estamos generando claves rsa, y nos gustaría almacenarlas como hashes base64 públicos y privados, como estoy acostumbrado a ver en mi carpeta ~/.ssh en mi caja de linuxgenerando claves públicas/privadas rsa serializadas de NED Big Ints

Sin embargo, estamos tratando con las primitivas RSA: los valores n, ey d.

¿Cómo puedo generar hashes base64 fuera de esos valores? Y viceversa (si no es obvio).

+0

Por qué no http://docs.python.org/3.4/library/base64.html y/o (https://pypi.python.org/pypi/rsa http://stuvel.eu/ rsa)? – user2284570

+0

@ J.Random alguna respuesta? – user2284570

Respuesta

2

base64 es un esquema de codificación para datos binarios representados como texto, no como un algoritmo hash. Si se refiere a la huella dactilar, es MD5.

Tanto para la huella dactilar como para los datos codificados en base64, puede consultar o incluso reutilizar Twisted's Conch implementation.

1

necesita usar la codificación ASN.1 correcta y luego base64.

Desafortunadamente, no tengo idea de cuál es la codificación correcta de ASN.1 (realmente no entiendo ASN.1). está integrado en openssl, pero no puedo encontrar una forma de acceder a él desde la línea de comandos. puede escribirlo desde C usando http://www.openssl.org/docs/crypto/RSA_print.html y http://www.openssl.org/docs/crypto/rsa.html

tiene python en las etiquetas. pyopenssl envuelve openssl y podría proporcionar una ruta más fácil - https://code.launchpad.net/pyopenssl - pero al mirar la fuente parece que son de un nivel demasiado alto (no parecen exponer la estructura de RSA).

si hablar ASN.1 (o tener una biblioteca que lo hace, como http://pyasn1.sourceforge.net/) entonces esto podría ser todo lo que necesita - https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem

(i cuenta de que esto es bastante incompleto - No estoy buscando para el recompensa, simplemente tirando lo que sé en caso de que sea suficiente para ayudar - básicamente "ASN.1 para DER" es la parte que te falta, es lo que define la estructura para que las diferentes partes puedan separarse cuando se vuelva a leer)

+0

La clave pública id_rsa.pub tiene un formato diferente, sin embargo, ver mi respuesta (se actualizará con los detalles). –

1

Voy a actualizar esto con más detalles y un decodificador cuando me libere en unas pocas horas.

def bitlength_and_integer_in_bytes(n): 
    bytes_length = n.bit_length()//8+1 
    return bytes_length.to_bytes(4, "big")+n.to_bytes(bytes_length, "big") 

def gen_id_rsa_pub(n,e): 
    return b"ssh-rsa "+base64.b64encode(b"\x00\x00\x00\x07ssh-rsa"+bitlength_and_integer_in_bytes(e)+bitlength_and_integer_in_bytes(n))+b" RSA key description" 
open("id_rsa.pub", "bw").write(gen_id_rsa_pub(n,e)) 
##import base64 
##from pyasn1.codec.der import decoder 
##s = "\n".join(open(".ssh/id_rsa").readlines()[1:-1]) 
##d = decoder.decode(base64.b64decode(s)) 
import base64 
from pyasn1.codec.der import encoder 
from pyasn1.type.univ import * 
#below from http://stackoverflow.com/a/9758173/443348 
def egcd(a, b): 
    if a == 0: 
     return (b, 0, 1) 
    else: 
     g, y, x = egcd(b % a, a) 
     return (g, x - (b // a) * y, y) 

def modinv(a, m): 
    g, x, y = egcd(a, m) 
    if g != 1: 
     raise Exception('modular inverse does not exist') 
    else: 
     return x % m 

#got example values from https://en.wikipedia.org/wiki/RSA_(algorithm)#A_working_example 
p = 61 
q = 53 
n = p*q #3233 
totient_n = (p-1)*(q-1) # 3120 
e = 17 # Should be coprime to 3120 
d = modinv(e, totient_n) #2753 

s = Sequence() 
def setvalues(sequence, values): 
    for index, value in enumerate(values): 
     sequence.setComponentByPosition(index, value) 

q = n/p 

setvalues(s, map(Integer, (0, n, e, d, p, q, d%(p-1), d%(q-1), modinv(q,p)))) 
id_rsa = b"-----BEGIN RSA PRIVATE KEY-----\n"+base64.b64encode(encoder.encode(s))+b"\n-----END RSA PRIVATE KEY-----\n" 
open("id_rsa", "bw").write(id_rsa) 
Cuestiones relacionadas