Formato de clave pública RSA

139

¿Dónde puedo encontrar documentación sobre el formato de una clave pública RSA?

Una clave pública RSA formateada por OpenSSH:

ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQB / nAmOjTmezNUDKYvEeIRf2YnwM9 / uUG1d0BYsc8 / tRtx + RGi7N2lUbp728MXGwdnL9od4cItzky / zVdLZE2cycOa18xBK9cOWmcKS0A8FYBxEQWJ / q9YVUgZbFKfYGaGQxsER + A0w / fX8ALuk78ktP31K69LcQgxIsl7rNzxsoOQKJ / CIxOGMMxczYTiEoLvQhapFQMs3FL96didKr / QbrfB1WT6s3838SEaXfgZvLef1YB2xmfhbT9OXFE3FXvh2UPBfN + ffE7iiayQf / 2XR + 8j4N4bW30DiPtOQLGUrH1y5X / rpNZNlWW2 + jGIxqZtgWg7lTy3mXy5x836Sj / 6L

La misma clave pública formateada para su uso en Secure Shell (RFC 4716 - El formato de archivo de clave pública de Secure Shell (SSH)) :

---- BEGIN SSH2 PUBLIC KEY ----
AAAAB3NzaC1yc2EAAAABJQAAAQB/nAmOjTmezNUDKYvEeIRf2YnwM9/uUG1d0BYs
c8/tRtx+RGi7N2lUbp728MXGwdnL9od4cItzky/zVdLZE2cycOa18xBK9cOWmcKS
0A8FYBxEQWJ/q9YVUgZbFKfYGaGQxsER+A0w/fX8ALuk78ktP31K69LcQgxIsl7r
NzxsoOQKJ/CIxOGMMxczYTiEoLvQhapFQMs3FL96didKr/QbrfB1WT6s3838SEaX
fgZvLef1YB2xmfhbT9OXFE3FXvh2UPBfN+ffE7iiayQf/2XR+8j4N4bW30DiPtOQ
LGUrH1y5X/rpNZNlWW2+jGIxqZtgWg7lTy3mXy5x836Sj/6L
---- END SSH2 PUBLIC KEY ----

La misma clave pública formateada como una clave pública RSA (tenga en cuenta las cinco - , y sin espacio):

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsu
ERwta7+fWIfxOo208ett/jhskiVodSEt3QBGh4XBipyWopKwZ93HHaDVZAALi/2A
+xTBtWdEo7XGUujKDvC2/aZKukfjpOiUI8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCw
mwSXA9VNmhz+PiB+Dml4WWnKW/VHo2ujTXxq7+efMU4H2fny3Se3KYOsFPFGZ1TN
QSYlFuShWrHPtiLmUdPoP6CV2mML1tk+l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P
+0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6YwIDAQAB
-----END RSA PUBLIC KEY-----

El volcado hexadecimal de los datos codificados en base 64:

00 00 00 07 73 73 68 2d 72 73 61 00 00 00 01 25 00 00 01 00 7f 9c 09
8e 8d 39 9e cc d5 03 29 8b c4 78 84 5f d9 89 f0 33 df ee 50 6d 5d d0 
16 2c 73 cf ed 46 dc 7e 44 68 bb 37 69 54 6e 9e f6 f0 c5 c6 c1 d9 cb
f6 87 78 70 8b 73 93 2f f3 55 d2 d9 13 67 32 70 e6 b5 f3 10 4a f5 c3 
96 99 c2 92 d0 0f 05 60 1c 44 41 62 7f ab d6 15 52 06 5b 14 a7 d8 19 
a1 90 c6 c1 11 f8 0d 30 fd f5 fc 00 bb a4 ef c9 2d 3f 7d 4a eb d2 dc 
42 0c 48 b2 5e eb 37 3c 6c a0 e4 0a 27 f0 88 c4 e1 8c 33 17 33 61 38 
84 a0 bb d0 85 aa 45 40 cb 37 14 bf 7a 76 27 4a af f4 1b ad f0 75 59 
3e ac df cd fc 48 46 97 7e 06 6f 2d e7 f5 60 1d b1 99 f8 5b 4f d3 97 
14 4d c5 5e f8 76 50 f0 5f 37 e7 df 13 b8 a2 6b 24 1f ff 65 d1 fb c8 
f8 37 86 d6 df 40 e2 3e d3 90 2c 65 2b 1f 5c b9 5f fa e9 35 93 65 59 
6d be 8c 62 31 a9 9b 60 5a 0e e5 4f 2d e6 5f 2e 71 f3 7e 92 8f fe 8b

He leído que hay un par de formatos 🕗 :

Los datos clave se pueden codificar de tres formas generales:

  • Formato binario codificado DER. Esto a veces se denomina codificación BER ASN.1
  • PEM o formato base64. Estos son los mismos datos que el archivo codificado DER pero está codificado en base64 con líneas adicionales de encabezado y pie de página
  • Formato XML.

Si es ASN.1 , el hexágono ciertamente no lo parece.

¿Cuál es el formato de una clave pública RSA?


Ver también

Ian Boyd
fuente

Respuestas:

68

No puede simplemente cambiar los delimitadores de ---- BEGIN SSH2 PUBLIC KEY ----a -----BEGIN RSA PUBLIC KEY-----y esperar que sea suficiente para convertir de un formato a otro (que es lo que ha hecho en su ejemplo).

Este artículo tiene una buena explicación sobre ambos formatos.

Lo que obtienes en una RSA PUBLIC KEYestá más cerca del contenido de una PUBLIC KEY, pero necesitas compensar el inicio de tu estructura ASN.1 para reflejar el hecho de que PUBLIC KEYtambién tiene un indicador que dice qué tipo de clave es (ver RFC 3447 ). Puede ver esto usando openssl asn1parsey -strparse 19, como se describe en esta respuesta .

EDITAR : Después de su edición, puede obtener los detalles de su RSA PUBLIC KEYestructura usando grep -v -- ----- | tr -d '\n' | base64 -d | openssl asn1parse -inform DER:

    0:d=0  hl=4 l= 266 cons: SEQUENCE          
    4:d=1  hl=4 l= 257 prim: INTEGER           :FB1199FF0733F6E805A4FD3B36CA68E94D7B974621162169C71538A539372E27F3F51DF3B08B2E111C2D6BBF9F5887F13A8DB4F1EB6DFE386C92256875212DDD00468785C18A9C96A292B067DDC71DA0D564000B8BFD80FB14C1B56744A3B5C652E8CA0EF0B6FDA64ABA47E3A4E89423C0212C07E39A5703FD467540F874987B209513429A90B09B049703D54D9A1CFE3E207E0E69785969CA5BF547A36BA34D7C6AEFE79F314E07D9F9F2DD27B72983AC14F1466754CD41262516E4A15AB1CFB622E651D3E83FA095DA630BD6D93E97B0C822A5EB4212D428300278CE6BA0CC7490B854581F0FFB4BA3D4236534DE09459942EF115FAA231B15153D67837A63
  265:d=1  hl=2 l=   3 prim: INTEGER           :010001

Para decodificar el formato de clave SSH, también debe usar la especificación de formato de datos en RFC 4251 , junto con RFC 4253:

   The "ssh-rsa" key format has the following specific encoding:

      string    "ssh-rsa"
      mpint     e
      mpint     n

Por ejemplo, al principio, obtienes 00 00 00 07 73 73 68 2d 72 73 61. Los primeros cuatro bytes ( 00 00 00 07) le dan la longitud. El resto es la cadena en sí: 73 = s, 68 = h, ... -> 73 73 68 2d 72 73 61= ssh-rsa, seguida del exponente de longitud 1 ( 00 00 00 01 25) y el módulo de longitud 256 ( 00 00 01 00 7f ...).

Bruno
fuente
2
Ese artículo menciona que el formato OpenSSH es un formato, pero no entra en detalles del formato. En cambio, menciona que el formato está completamente documentado en RFC 4253 - Protocolo de capa de transporte de Secure Shell (SSH) - Sección 6.6. Algoritmos de clave pública ; excepto que no puedo encontrar ninguna documentación allí. Actualicé la pregunta para usar la clave RSA pública de alguien que encontré.
Ian Boyd
Creo que el primer enlace se ha movido a blog.oddbit.com/2011/05/08/converting-openssh-public-keys
mbargiel
Puede usar openssl asn1parse -inform PEMcon -----BEGIN RSA PUBLIC KEY----datos o cualquier otra estructura PEM. Mucho más fácil que tratar de manipular manualmente los encabezados con los comandos grep / tr / base64.
davenpcj
55

A partir de los datos decodificados en base64 de una clave OpenSSL rsa-ssh , he podido adivinar un formato:

  • 00 00 00 07: prefijo de longitud de cuatro bytes (7 bytes)
  • 73 73 68 2d 72 73 61: "ssh-rsa"
  • 00 00 00 01: prefijo de longitud de cuatro bytes (1 byte)
  • 25: Exponente RSA ( e): 25
  • 00 00 01 00: prefijo de longitud de cuatro bytes (256 bytes)
  • Módulo RSA ( n):

    7f 9c 09 8e 8d 39 9e cc d5 03 29 8b c4 78 84 5f
    d9 89 f0 33 df ee 50 6d 5d d0 16 2c 73 cf ed 46 
    dc 7e 44 68 bb 37 69 54 6e 9e f6 f0 c5 c6 c1 d9 
    cb f6 87 78 70 8b 73 93 2f f3 55 d2 d9 13 67 32 
    70 e6 b5 f3 10 4a f5 c3 96 99 c2 92 d0 0f 05 60 
    1c 44 41 62 7f ab d6 15 52 06 5b 14 a7 d8 19 a1 
    90 c6 c1 11 f8 0d 30 fd f5 fc 00 bb a4 ef c9 2d 
    3f 7d 4a eb d2 dc 42 0c 48 b2 5e eb 37 3c 6c a0 
    e4 0a 27 f0 88 c4 e1 8c 33 17 33 61 38 84 a0 bb 
    d0 85 aa 45 40 cb 37 14 bf 7a 76 27 4a af f4 1b 
    ad f0 75 59 3e ac df cd fc 48 46 97 7e 06 6f 2d 
    e7 f5 60 1d b1 99 f8 5b 4f d3 97 14 4d c5 5e f8 
    76 50 f0 5f 37 e7 df 13 b8 a2 6b 24 1f ff 65 d1 
    fb c8 f8 37 86 d6 df 40 e2 3e d3 90 2c 65 2b 1f 
    5c b9 5f fa e9 35 93 65 59 6d be 8c 62 31 a9 9b 
    60 5a 0e e5 4f 2d e6 5f 2e 71 f3 7e 92 8f fe 8b
    

La validación más cercana de mi teoría la puedo encontrar en RFC 4253:

El formato de clave "ssh-rsa" tiene la siguiente codificación específica:

  string    "ssh-rsa"
  mpint     e
  mpint     n

Aquí los parámetros 'e' y 'n' forman el blob clave de firma.

Pero no explica los prefijos de longitud.


Tomando el azar que RSA PUBLIC KEYencontré (en la pregunta) y decodificando la base64 en hexadecimal:

30 82 01 0a 02 82 01 01 00 fb 11 99 ff 07 33 f6 e8 05 a4 fd 3b 36 ca 68 
e9 4d 7b 97 46 21 16 21 69 c7 15 38 a5 39 37 2e 27 f3 f5 1d f3 b0 8b 2e 
11 1c 2d 6b bf 9f 58 87 f1 3a 8d b4 f1 eb 6d fe 38 6c 92 25 68 75 21 2d 
dd 00 46 87 85 c1 8a 9c 96 a2 92 b0 67 dd c7 1d a0 d5 64 00 0b 8b fd 80 
fb 14 c1 b5 67 44 a3 b5 c6 52 e8 ca 0e f0 b6 fd a6 4a ba 47 e3 a4 e8 94 
23 c0 21 2c 07 e3 9a 57 03 fd 46 75 40 f8 74 98 7b 20 95 13 42 9a 90 b0 
9b 04 97 03 d5 4d 9a 1c fe 3e 20 7e 0e 69 78 59 69 ca 5b f5 47 a3 6b a3 
4d 7c 6a ef e7 9f 31 4e 07 d9 f9 f2 dd 27 b7 29 83 ac 14 f1 46 67 54 cd 
41 26 25 16 e4 a1 5a b1 cf b6 22 e6 51 d3 e8 3f a0 95 da 63 0b d6 d9 3e 
97 b0 c8 22 a5 eb 42 12 d4 28 30 02 78 ce 6b a0 cc 74 90 b8 54 58 1f 0f 
fb 4b a3 d4 23 65 34 de 09 45 99 42 ef 11 5f aa 23 1b 15 15 3d 67 83 7a 
63 02 03 01 00 01

De RFC3447 - Estándares de criptografía de clave pública (PKCS) # 1: Especificaciones de criptografía RSA Versión 2.1 :

A.1.1 Sintaxis de clave pública RSA

Una clave pública RSA debe representarse con el tipo ASN.1 RSAPublicKey:

  RSAPublicKey ::= SEQUENCE {
     modulus           INTEGER,  -- n
     publicExponent    INTEGER   -- e
  }

Los campos de tipo RSAPublicKey tienen los siguientes significados:

  • módulo es el módulo RSA n.
  • publicExponent es el exponente público de RSA e.

Utilizando la excelente documentación ASN.1 de Microsoft (y la única real) :

30 82 01 0a       ;SEQUENCE (0x010A bytes: 266 bytes)
|  02 82 01 01    ;INTEGER  (0x0101 bytes: 257 bytes)
|  |  00          ;leading zero because high-bit, but number is positive
|  |  fb 11 99 ff 07 33 f6 e8 05 a4 fd 3b 36 ca 68 
|  |  e9 4d 7b 97 46 21 16 21 69 c7 15 38 a5 39 37 2e 27 f3 f5 1d f3 b0 8b 2e 
|  |  11 1c 2d 6b bf 9f 58 87 f1 3a 8d b4 f1 eb 6d fe 38 6c 92 25 68 75 21 2d 
|  |  dd 00 46 87 85 c1 8a 9c 96 a2 92 b0 67 dd c7 1d a0 d5 64 00 0b 8b fd 80 
|  |  fb 14 c1 b5 67 44 a3 b5 c6 52 e8 ca 0e f0 b6 fd a6 4a ba 47 e3 a4 e8 94 
|  |  23 c0 21 2c 07 e3 9a 57 03 fd 46 75 40 f8 74 98 7b 20 95 13 42 9a 90 b0 
|  |  9b 04 97 03 d5 4d 9a 1c fe 3e 20 7e 0e 69 78 59 69 ca 5b f5 47 a3 6b a3 
|  |  4d 7c 6a ef e7 9f 31 4e 07 d9 f9 f2 dd 27 b7 29 83 ac 14 f1 46 67 54 cd 
|  |  41 26 25 16 e4 a1 5a b1 cf b6 22 e6 51 d3 e8 3f a0 95 da 63 0b d6 d9 3e 
|  |  97 b0 c8 22 a5 eb 42 12 d4 28 30 02 78 ce 6b a0 cc 74 90 b8 54 58 1f 0f 
|  |  fb 4b a3 d4 23 65 34 de 09 45 99 42 ef 11 5f aa 23 1b 15 15 3d 67 83 7a 
|  |  63 
|  02 03          ;INTEGER (3 bytes)
|     01 00 01

dando el módulo de clave pública y exponente:

  • módulo =0xfb1199ff0733f6e805a4fd3b36ca68...837a63
  • exponente = 65,537

Actualización : mi forma ampliada de esta respuesta en otra pregunta

Ian Boyd
fuente
1
RSA PUBLIC KEYsigue el formulario ASN.1 (consulte la especificación PKCS), no tiene nada que ver con el formato de OpenSSH.
Bruno
3
Gran respuesta, muchas gracias. El "cero inicial porque el bit alto pero el número es positivo" lo convierte en el formato de clave ssh-rsa según la fuente. La pista más útil sobre esto que puedo encontrar es un comentario en github.com/openssh/openssh-portable que dice "/ * Si MSB está configurado, anteponga un \ 0 * /" al escribir bignums en el formato ssh-rsa. Esto solo parece ser un problema para el módulo público el 50% (?) Del tiempo y nunca en el exponente público debido a la naturaleza de las claves RSA generadas.
Tim Potter
gran respuesta, sobre stringy mpint - se describe en RFC 4251, sección 5, no es necesario preguntar :)
usuario1516873
10

Decodificador de referencia de CRL, CRT, CSR, NEW CSR, PRIVATE KEY, PUBLIC KEY, RSA, RSA Public Key Parser

Clave pública RSA

-----BEGIN RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----

Clave privada encriptada

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
-----END RSA PRIVATE KEY-----

CRL

-----BEGIN X509 CRL-----
-----END X509 CRL-----

CRT

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

RSE

-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----

NUEVA RSE

-----BEGIN NEW CERTIFICATE REQUEST-----
-----END NEW CERTIFICATE REQUEST-----

PEM

-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

PKCS7

-----BEGIN PKCS7-----
-----END PKCS7-----

LLAVE PRIVADA

-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----

DSA KEY

-----BEGIN DSA PRIVATE KEY-----
-----END DSA PRIVATE KEY-----

Curva elíptica

-----BEGIN EC PRIVATE KEY-----
-----END EC PRIVATE KEY-----

Clave privada PGP

-----BEGIN PGP PRIVATE KEY BLOCK-----
-----END PGP PRIVATE KEY BLOCK-----

Clave pública PGP

-----BEGIN PGP PUBLIC KEY BLOCK-----
-----END PGP PUBLIC KEY BLOCK-----
anish
fuente