Format de clé publique RSA

139

Où puis-je trouver de la documentation sur le format d'une clé publique RSA?

Une clé publique RSA formatée par OpenSSH:

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

La même clé publique formatée pour une utilisation dans Secure Shell (RFC 4716 - The Secure Shell (SSH) Public Key File Format) :

---- 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 même clé publique formatée en tant que clé publique RSA (notez les cinq - et pas d'espace):

-----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-----

Le vidage hexadécimal des données encodées 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

J'ai lu qu'il existe plusieurs formats 🕗 :

Les données clés peuvent être codées de trois manières générales:

  • Format codé DER binaire. Ceci est parfois appelé codé ASN.1 BER
  • Format PEM ou base64. Il s'agit des mêmes données que le fichier encodé DER mais il est encodé en base64 avec des lignes d'en-tête et de pied de page supplémentaires
  • Format XML.

Si c'est ASN.1 , l'hexagone ne lui ressemble certainement pas.

Quel est le format d'une clé publique RSA?


Voir également

Ian Boyd
la source

Réponses:

68

Vous ne pouvez pas simplement changer les délimiteurs de ---- BEGIN SSH2 PUBLIC KEY ----à -----BEGIN RSA PUBLIC KEY-----et vous attendre à ce qu'il suffise de convertir d'un format à un autre (ce que vous avez fait dans votre exemple).

Cet article a une bonne explication sur les deux formats.

Ce que vous obtenez dans un RSA PUBLIC KEYest plus proche du contenu de a PUBLIC KEY, mais vous devez compenser le début de votre structure ASN.1 pour refléter le fait quePUBLIC KEY également un indicateur indiquant de quel type de clé il s'agit (voir RFC 3447 ). Vous pouvez le voir en utilisant openssl asn1parseet -strparse 19, comme décrit dans cette réponse .

EDIT : Suite à votre modification, vous pouvez obtenir les détails de votre RSA PUBLIC KEYstructure en utilisant 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

Pour décoder le format de clé SSH, vous devez utiliser la spécification de format de données dans RFC 4251 , conjointement avec RFC 4253:

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

      string    "ssh-rsa"
      mpint     e
      mpint     n

Par exemple, au début, vous obtenez 00 00 00 07 73 73 68 2d 72 73 61. Les quatre premiers octets ( 00 00 00 07) vous donnent la longueur. Le reste est la chaîne elle-même: 73 = s, 68 = h, ... -> 73 73 68 2d 72 73 61= ssh-rsa, suivi de l'exposant de longueur 1 ( 00 00 00 01 25) et du module de longueur 256 ( 00 00 01 00 7f ...).

Bruno
la source
2
Cet article mentionne que le format OpenSSH est un format, mais n'entre pas dans les détails du format. Au lieu de cela, il mentionne que le format est entièrement documenté dans RFC 4253 - Le protocole de couche de transport Secure Shell (SSH) - Section 6.6. Algorithmes de clé publique ; sauf que je ne trouve aucune documentation là-bas. J'ai mis à jour la question pour utiliser la clé RSA publique de quelqu'un que j'ai trouvée.
Ian Boyd
Je crois que le premier lien a été déplacé vers blog.oddbit.com/2011/05/08/converting-openssh-public-keys
mbargiel
Vous pouvez utiliser openssl asn1parse -inform PEMavec des -----BEGIN RSA PUBLIC KEY----données ou toute autre structure PEM. Beaucoup plus facile que d'essayer de manipuler manuellement les en-têtes avec les commandes grep / tr / base64.
davenpcj
55

À partir des données décodées en base64 d'une clé OpenSSL rsa-ssh , j'ai pu deviner un format:

  • 00 00 00 07: préfixe de longueur de quatre octets (7 octets)
  • 73 73 68 2d 72 73 61: "ssh-rsa"
  • 00 00 00 01: préfixe de longueur de quatre octets (1 octet)
  • 25: Exposant RSA ( e): 25
  • 00 00 01 00: préfixe de longueur de quatre octets (256 octets)
  • Module 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 validation la plus proche de ma théorie, je peux la trouver à partir de la RFC 4253:

Le format de clé "ssh-rsa" a le codage spécifique suivant:

  string    "ssh-rsa"
  mpint     e
  mpint     n

Ici, les paramètres «e» et «n» forment le blob de clé de signature.

Mais cela n'explique pas les préfixes de longueur.


Prenant le hasard que RSA PUBLIC KEYj'ai trouvé (dans la question), et décodant le base64 en hexadécimal:

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 - Public-Key Cryptography Standards (PKCS) # 1: RSA Cryptography Specifications Version 2.1 :

A.1.1 Syntaxe de la clé publique RSA

Une clé publique RSA doit être représentée avec le type ASN.1 RSAPublicKey:

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

Les champs de type RSAPublicKey ont les significations suivantes:

  • module est le module RSA n.
  • publicExponent est l'exposant public RSA e.

En utilisant l'excellente (et la seule vraie) documentation ASN.1 de Microsoft :

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

donnant le module et l'exposant de la clé publique:

  • module =0xfb1199ff0733f6e805a4fd3b36ca68...837a63
  • exposant = 65 537

Mise à jour : Ma forme développée de cette réponse dans une autre question

Ian Boyd
la source
1
RSA PUBLIC KEYsuit la forme ASN.1 (voir la spécification PKCS), cela n'a rien à voir avec le format d'OpenSSH.
Bruno
3
Excellente réponse - merci beaucoup. Le "zéro non significatif car le bit haut mais le nombre est positif" le transforme au format de clé ssh-rsa selon la source. L'astuce la plus utile à ce sujet que je puisse trouver est un commentaire dans github.com/openssh/openssh-portable qui dit "/ * Si MSB est défini, ajoutez un \ 0 * /" avant d'écrire des bignums au format ssh-rsa. Cela ne semble être un problème que pour le module public 50% (?) Du temps et jamais dans l'exposant public en raison de la nature des clés RSA générées.
Tim Potter
excellente réponse, à propos stringet mpint - il est décrit dans la RFC 4251, section 5, pas besoin de quesser :)
user1516873
10

Décodeur de référence de CRL, CRT, CSR, NEW CSR, PRIVATE KEY, PUBLIC KEY, RSA, RSA Public Key Parser

Clé publique RSA

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

Clé privée chiffrée

-----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-----

NOUVEAU CSR

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

PEM

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

PKCS7

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

CLÉ PRIVÉE

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

CLÉ DSA

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

Courbe elliptique

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

Clé privée PGP

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

Clé publique PGP

-----BEGIN PGP PUBLIC KEY BLOCK-----
-----END PGP PUBLIC KEY BLOCK-----
anish
la source