¿Usar clave privada RSA para generar clave pública?


394

Realmente no entiendo este:

de acuerdo con: http://www.madboa.com/geek/openssl/#key-rsa , puede generar una clave pública a partir de una clave privada.

openssl genrsa -out mykey.pem 1024
openssl rsa -in mykey.pem -pubout > mykey.pub

Mi pensamiento inicial fue que se generan en un par juntos. ¿La clave privada RSA contiene la suma? o la clave pública?


1
Para todos los que usan rsa y openssl y desean cifrar un archivo grande como 5 Kbyte. recuerde que la clave pública debe ser proporcional o mayor en tamaño a lo que desea cifrar; de lo contrario, obtendrá un "archivo demasiado grande para que se cifre". Resumo que genera una clave privada bastante grande y seria y, a partir de eso, crea sus claves privadas para que tenga muchos datos con los que trabajar. Le dije a quien conozco en openssl sobre la falla, y que deberían hacer que se repita por sí misma, de lo contrario, usará mucho tiempo para descubrir por qué se queja del tamaño.
Kent Hansen

10
El problema que describe Kent Hansen se debe al uso de RSA directamente en datos de texto sin formato, lo que nunca debe hacerse en ningún caso por razones de seguridad. En su lugar, utilice un esquema de cifrado híbrido bien analizado como RSA-KEM ( tools.ietf.org/html/rfc5990#appendix-A ), con un esquema de cifrado simétrico autenticado como cifrar y luego HMAC aplicado a los datos.
Daira Hopwood



La respuesta de @ SteffenUllrich en este enlace explica por qué: security.stackexchange.com/questions/172274/…
bearzyj

Respuestas:


578
openssl genrsa -out mykey.pem 1024

en realidad producirá un par de claves pública - privada. El par se almacena en el mykey.pemarchivo generado .

openssl rsa -in mykey.pem -pubout > mykey.pub

extraerá la clave pública e imprimirá eso. Aquí hay un enlace a una página que describe esto mejor.

EDITAR: Consulte la sección de ejemplos aquí . Para generar solo la parte pública de una clave privada:

openssl rsa -in key.pem -pubout -out pubkey.pem

Para obtener una clave pública utilizable para propósitos SSH, use ssh-keygen :

ssh-keygen -y -f key.pem > key.pub

50
Es confuso cómo todos en los tutoriales en todas partes dicen que usando el comando openssl genrsa generarás la CLAVE PRIVADA, porque se están olvidando de que también está generando la CLAVE PÚBLICA
Jaime Hablutzel

15
@jaime, ¿realmente puedes culparlos? La documentación oficial no dice absolutamente nada sobre una clave pública. "DESCRIPCIÓN: El comando genrsa genera una clave privada RSA". openssl.org/docs/apps/genrsa.html
Despertar

124
@jaime, eso es porque no lo hace: genrsa solo genera la clave privada, la clave pública no se almacena. Sin embargo, si tiene la clave privada, puede calcular (derivar) la clave pública a partir de ella, que es lo que hace el segundo comando anterior. Calcula, no extrae, la clave pública.
steveayre

13
@steveayre Tenía entendido que las claves RSA eran simplemente los dos exponentes ( ey den la literatura común). Ninguno de los dos es matemáticamente privado o público, esas son etiquetas que se asignan arbitrariamente en el momento de la creación. Podrían asignarse con la misma facilidad a la inversa. Generar uno del otro es un problema equivalente. El .pemformato contiene una gran cantidad de información, incluidos ambos exponentes y, por lo tanto, ambas claves, ¿verdad?
lincha

13
@steveayre está mayormente equivocado. Los componentes clave de RSA públicos (n, e) SE generan y se incrustan en el archivo de clave RSA privado creado con el openssl genrsacomando. Sin embargo, no se crea un archivo de clave pública separado en el mismo paso. Para extraer la clave pública del archivo de clave privada en un archivo de clave pública separado, use su openssl rsa -in private.pem -pubout -out public.pemcomando. Cuando produce una clave pública de esta manera, se extrae del archivo de clave privada, no se calcula. Vea mi respuesta a continuación para más detalles.
Golem

273

Personas que buscan clave pública SSH ...

Si está buscando extraer la clave pública para usar con OpenSSH, necesitará obtener la clave pública de manera un poco diferente

$ ssh-keygen -y -f mykey.pem > mykey.pub

Este formato de clave pública es compatible con OpenSSH. Agregue la clave pública remote:~/.ssh/authorized_keysy estará listo para comenzar


documentos de SSH-KEYGEN(1)

ssh-keygen -y [-f input_keyfile]  

-y Esta opción leerá un archivo de formato OpenSSH privado e imprimirá una clave pública de OpenSSH para stdout.


3
Esto funciona como un encanto! ¡Genera un formato que Github toma! Github no toma el formato PEM. La respuesta anterior sugerida openssl rsa -in key.pem -pubout -out pubkey.pemno fue aceptada, ya que evidentemente el resultado es una clave pública en formato pem. Entonces recibí este error: "La clave no es válida. Debe comenzar con 'ssh-rsa' o 'ssh-dss'. Verifique que esté copiando la mitad pública de la clave". Sin embargo, ssh-keygen -y [-f input_keyfile] genera el formato correcto que Github toma.
Devy

71

En la mayoría del software que genera claves privadas RSA, incluidas las de openssl, la clave privada se representa como un objeto PKCS # 1 RSAPrivatekey o alguna variante del mismo:

A.1.2 Sintaxis de clave privada RSA

Una clave privada RSA debe representarse con el tipo ASN.1
RSAPrivateKey:

  RSAPrivateKey ::= SEQUENCE {
      version           Version,
      modulus           INTEGER,  -- n
      publicExponent    INTEGER,  -- e
      privateExponent   INTEGER,  -- d
      prime1            INTEGER,  -- p
      prime2            INTEGER,  -- q
      exponent1         INTEGER,  -- d mod (p-1)
      exponent2         INTEGER,  -- d mod (q-1)
      coefficient       INTEGER,  -- (inverse of q) mod p
      otherPrimeInfos   OtherPrimeInfos OPTIONAL
  }

Como puede ver, este formato tiene una serie de campos que incluyen el módulo y el exponente público y, por lo tanto, es un superconjunto estricto de la información en una clave pública RSA .


¿Quiere decir que dada una clave privada, es matemáticamente factible generar la clave pública? ¿No es la fuerza de RSA el hecho de que es computacionalmente inviable generar una clave dada la otra?
Raam

30
@Raam: No, la fortaleza de RSA es que no es factible generar la clave privada del público. Generar la forma pública lo privado es trivial.
Presidente James K. Polk

@GregS, ¿por qué? Una clave consta de un módulo y un exponente. Si el otro exponente se puede calcular a partir de estos dos números, RSA se descifraría fácilmente. Entonces, ¿la clave privada de OpenSSL contiene más que exponente y módulo?
Calmarius

1
@ Calmarius: ¿Quién dice que una clave consiste en un módulo y exponente? Esa sería la clave privada mínima, pero generalmente la clave privada incluye otros componentes como los factores primos. Lea la respuesta para los detalles.
Presidente James K. Polk

1
@JamesKPolk Eso no es necesariamente cierto. Si el exponente público es grande (es decir, tiene las mismas propiedades que el exponente privado), entonces la clave pública puede ser imposible de reconstruir. La mayoría de las bibliotecas no admitirán esto, pero el criptosistema RSA ciertamente no requiere que reconstruya la clave pública a partir de la clave privada.
Maarten Bodewes

34

Mi respuesta a continuación es un poco larga, pero espero que brinde algunos detalles que faltan en las respuestas anteriores. Comenzaré con algunas declaraciones relacionadas y finalmente responderé la pregunta inicial.

Para cifrar algo utilizando el algoritmo RSA, necesita un par de exponente de módulo y cifrado (público) (n, e). Esa es tu clave pública. Para descifrar algo utilizando el algoritmo RSA, necesita un par de exponentes de módulo y descifrado (privado) (n, d). Esa es tu clave privada.

Para cifrar algo usando la clave pública RSA, trata su texto sin formato como un número y lo eleva a la potencia del módulo n:

ciphertext = ( plaintext^e ) mod n

Para descifrar algo utilizando la clave privada RSA, trata el texto cifrado como un número y lo eleva a la potencia del módulo d n:

plaintext = ( ciphertext^d ) mod n

Para generar una clave privada (d, n) usando openssl puede usar el siguiente comando:

openssl genrsa -out private.pem 1024

Para generar una clave pública (e, n) a partir de la clave privada usando openssl, puede usar el siguiente comando:

openssl rsa -in private.pem -out public.pem -pubout

Para analizar el contenido de la clave privada RSA private.pem generada por el comando openssl anterior, ejecute lo siguiente (salida truncada en las etiquetas aquí):

openssl rsa -in private.pem -text -noout | less

modulus         - n
privateExponent - d
publicExponent  - e
prime1          - p
prime2          - q
exponent1       - d mod (p-1)
exponent2       - d mod (q-1)
coefficient     - (q^-1) mod p

¿No debería la clave privada consistir solo en (n, d) par? ¿Por qué hay 6 componentes adicionales? Contiene e (exponente público) para que la clave RSA pública se pueda generar / extraer / derivar de la clave privada RSA private.pem. Los 5 componentes restantes están ahí para acelerar el proceso de descifrado. Resulta que al precalcular y almacenar esos 5 valores es posible acelerar el descifrado RSA por el factor 4. El descifrado funcionará sin esos 5 componentes, pero se puede hacer más rápido si los tiene a mano. El algoritmo de aceleración se basa en el teorema del resto chino .

Sí, la clave privada private.pem RSA en realidad contiene todos esos 8 valores; ninguno de ellos se genera sobre la marcha cuando ejecuta el comando anterior. Intente ejecutar los siguientes comandos y compare la salida:

# Convert the key from PEM to DER (binary) format
openssl rsa -in private.pem -outform der -out private.der

# Print private.der private key contents as binary stream
xxd -p private.der

# Now compare the output of the above command with output 
# of the earlier openssl command that outputs private key
# components. If you stare at both outputs long enough
# you should be able to confirm that all components are
# indeed lurking somewhere in the binary stream
openssl rsa -in private.pem -text -noout | less

El PKCS # 1 v1.5 recomienda esta estructura de la clave privada RSA como una representación alternativa ( segunda ). El estándar PKCS # 1 v2.0 excluye los exponentes eyd de la representación alternativa por completo. PKCS # 1 v2.1 y v2.2 proponen más cambios a la representación alternativa, al incluir opcionalmente más componentes relacionados con CRT.

Para ver el contenido de la clave pública RSA public.pem, ejecute lo siguiente (salida truncada a etiquetas aquí):

openssl rsa -in public.pem -text -pubin -noout

Modulus             - n
Exponent (public)   - e

No hay sorpresas aquí. Es solo (n, e) par, como se prometió.

Ahora, finalmente, respondo a la pregunta inicial: como se mostró anteriormente, la clave RSA privada generada con openssl contiene componentes de claves públicas y privadas y algunos más. Cuando genera / extrae / deriva la clave pública de la clave privada, openssl copia dos de esos componentes (e, n) en un archivo separado que se convierte en su clave pública.


usted escribió "Para generar una clave pública (d, n) a partir de la clave privada ...". ¿No debería ser "(e, n)"? ¡Gracias por la gran respuesta!
elactic

Está comparando la 'sintaxis' (externa) en v1.5 con la semántica en versiones posteriores; verifique 2.0 # 11.1.2 y 2.1 y 2.2 # A.1.2 y verá que n, e, d todavía están presentes. (Como ya señaló la respuesta de James Polk.)
dave_thompson_085

1
Increíble explicación. Gracias
Francisco Albert

1
Parece que el exponente público ees siempre 65537 0x010001. Probablemente sea de facto elegir el exponente público y esta es probablemente la razón por la que genrsase explica en la página del manual, y casi en todos los lugares to generate the private key. El público es algo obvio.
champú

¿Puedo calcular el (n, e) solo a partir de (n, d)?
Flyq

21

La clave pública no se almacena en el archivo PEM como algunas personas piensan. La siguiente estructura DER está presente en el archivo de clave privada:

openssl rsa -text -in mykey.pem

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

Entonces, hay suficientes datos para calcular la clave pública (módulo y exponente público), que es lo que openssl rsa -in mykey.pem -pubouthace


Veo que la clave pública no está almacenada allí, aunque es derivable como la clave privada, ¡pero tampoco veo la clave privada almacenada allí! Sin embargo, si encuentro el archivo pem, veo que dice clave privada y algunos ascii.
barlop

2
La clave privada también se deriva, mira el campo privateExponent. Puede ver los campos usando openssl rsa -text -in mykey.pem
Uxio

2
La clave pública se almacena realmente en el pem, porque el pem también incluye eyd, es decir, la clave pública. A diferencia de los algos de registro discretos, la clave pública rsa no puede calcularse simplemente a partir de la clave privada (d, n). Está allí solo porque las especificaciones de rsa indican almacenarlo con la clave privada y otra información.
Michael Chourdakis

1
Sí, esta respuesta se encuentra en todas las intenciones y propósitos MAL . Tanto el exponente público como el módulo están allí, por lo que la clave pública está ciertamente presente. No hay necesidad del exponente público allí que no sea recuperar fácilmente la clave pública sin ningún cálculo .
Maarten Bodewes

1
@MaartenBodewes: La respuesta es correcta. Lo que se cita se toma del RFC relevante como los valores almacenados para una clave PRIVADA. Que dos de los valores también se usen / solo para el cifrado de clave pública no cambia que se trata de datos de clave privada. He aprendido todo esto en los últimos dos días, no haciendo preguntas, sino mirando hacia arriba y leyendo el estándar relevante. Ahora entiendo todo sobre ASN.1, DER, PEM y RSA (bueno, tal vez NO TODO sobre RSA).
AlastairG

8

aquí, en este código, primero estamos creando una clave RSA que es privada pero también tiene un par de su clave pública, así que para obtener su clave pública real, simplemente hacemos esto

openssl rsa -in mykey.pem -pubout > mykey.pub

espero que lo obtengas para más información revisa esto


6

En primer lugar, un resumen rápido de la generación de claves RSA.

  1. Elija aleatoriamente dos primos probables aleatorios del tamaño apropiado (p y q).
  2. Multiplique los dos primos juntos para producir el módulo (n).
  3. Elija un exponente público (e).
  4. Haz algunos cálculos con los números primos y el exponente público para producir el exponente privado (d).

La clave pública consta del módulo y el exponente público.

Una clave privada mínima consistiría en el módulo y el exponente privado. No existe una forma segura de calcular desde un módulo conocido y un exponente privado hasta el exponente público correspondiente.

Sin embargo:

  1. Los formatos prácticos de clave privada casi siempre almacenan más de n y d.
  2. Normalmente, e no se selecciona al azar, se utiliza uno de los pocos valores conocidos. Si e es uno de los valores conocidos y conoce d, entonces sería fácil determinar e por prueba y error.

Entonces, en las implementaciones RSA más prácticas, puede obtener la clave pública de la clave privada. Sería posible construir un criptosistema basado en RSA donde esto no fuera posible, pero no es lo que se hizo.


1
Use the following commands:

1. openssl req -x509 -nodes -days 365 -sha256 -newkey rsa:2048 -keyout mycert.pem -out mycert.pem

Loading 'screen' into random state - done
Generating a 2048 bit RSA private key
.............+++
..................................................................................................................................................................+++
writing new private key to 'mycert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.

2. If you check there will be a file created by the name : mycert.pem

3. openssl rsa -in mycert.pem -pubout > mykey.txt
writing RSA key

4. If you check the same file location a new public key : mykey.txt will be created.

1
Esto es tonto; no hay necesidad de hacer un esfuerzo adicional para crear un certificado inútil cuando todo lo que desea es un par de llaves. Para alguna otra Q donde desee un certificado, esta podría ser una respuesta.
dave_thompson_085
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.