web-dev-qa-db-fra.com

RSA: Obtenir exposant et module à partir d'une clé publique

J'ai besoin de chiffrer des données en utilisant RSA en JavaScript. Toutes les bibliothèques autour demandent un exposant et un module, mais je ne reçois qu'un seul fichier public.key de mon adversaire. 

Comment récupérer la partie publique exponent et modulus à partir d'un fichier RSA?

40
Pierre Spring

Cela dépend des outils que vous pouvez utiliser. Je doute qu'il y ait aussi un JavaScript qui pourrait le faire directement dans le navigateur. Cela dépend également du fait qu'il s'agisse d'un élément unique (toujours la même clé) ou de la nécessité de le scripter.

Ligne de commande/OpenSSL

Si vous voulez utiliser quelque chose comme OpenSSL sur une ligne de commande unix, vous pouvez faire quelque chose comme suit:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmBAjFv+29CaiQqYZIw4P
J0q5Qz2gS7kbGleS3ai8Xbhu5n8PLomldxbRz0RpdCuxqd1yvaicqpDKe/TT09sR
mL1h8Sx3Qa3EQmqI0TcEEqk27Ak0DTFxuVrq7c5hHB5fbJ4o7iEq5MYfdSl4pZax
UxdNv4jRElymdap8/iOo3SU1RsaK6y7kox1/tm2cfWZZhMlRFYJnpoXpyNYrp+Yo
CNKxmZJnMsS698kaFjDlyznLlihwMroY0mQvdD7dCeBoVlfPUGPAlamwWyqtIU+9
5xVkSp3kxcNcNb/mePSKQIPafQ1sAmBKPwycA/1I5nLzDVuQa95ZWMn0JkphtFIh
HQIDAQAB
-----END PUBLIC KEY-----

Ensuite, les commandes seraient:

PUBKEY=`grep -v -- ----- public.key | tr -d '\n'`

Ensuite, vous pouvez regarder dans la structure ASN.1:

echo $PUBKEY | base64 -d | openssl asn1parse -inform DER -i

Cela devrait vous donner quelque chose comme ça:

    0:d=0  hl=4 l= 290 cons: SEQUENCE          
    4:d=1  hl=2 l=  13 cons:  SEQUENCE          
    6:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
   17:d=2  hl=2 l=   0 prim:   NULL              
   19:d=1  hl=4 l= 271 prim:  BIT STRING 

Le module et l'exposant public sont dans la dernière chaîne de bits, décalage 19, utilisez donc -strparse:

 echo $PUBKEY | base64 -d | openssl asn1parse -inform DER -i -strparse 19

Cela vous donnera le module et l'exposant public, en hexadécimal (les deux entiers):

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

C'est probablement bien si c'est toujours la même clé, mais ce n'est probablement pas très pratique de mettre un script.

Alternativement (et cela pourrait être plus facile à mettre dans un script),

openssl rsa -pubin -inform PEM -text -noout < public.key

retournera ceci:

Modulus (2048 bit):
    00:98:10:23:16:ff:b6:f4:26:a2:42:a6:19:23:0e:
    0f:27:4a:b9:43:3d:a0:4b:b9:1b:1a:57:92:dd:a8:
    bc:5d:b8:6e:e6:7f:0f:2e:89:a5:77:16:d1:cf:44:
    69:74:2b:b1:a9:dd:72:bd:a8:9c:aa:90:ca:7b:f4:
    d3:d3:db:11:98:bd:61:f1:2c:77:41:ad:c4:42:6a:
    88:d1:37:04:12:a9:36:ec:09:34:0d:31:71:b9:5a:
    ea:ed:ce:61:1c:1e:5f:6c:9e:28:ee:21:2a:e4:c6:
    1f:75:29:78:a5:96:b1:53:17:4d:bf:88:d1:12:5c:
    a6:75:aa:7c:fe:23:a8:dd:25:35:46:c6:8a:eb:2e:
    e4:a3:1d:7f:b6:6d:9c:7d:66:59:84:c9:51:15:82:
    67:a6:85:e9:c8:d6:2b:a7:e6:28:08:d2:b1:99:92:
    67:32:c4:ba:f7:c9:1a:16:30:e5:cb:39:cb:96:28:
    70:32:ba:18:d2:64:2f:74:3e:dd:09:e0:68:56:57:
    cf:50:63:c0:95:a9:b0:5b:2a:ad:21:4f:bd:e7:15:
    64:4a:9d:e4:c5:c3:5c:35:bf:e6:78:f4:8a:40:83:
    da:7d:0d:6c:02:60:4a:3f:0c:9c:03:fd:48:e6:72:
    f3:0d:5b:90:6b:de:59:58:c9:f4:26:4a:61:b4:52:
    21:1d
Exponent: 65537 (0x10001)

Java

Cela dépend du format d'entrée. S'il s'agit d'un certificat X.509 dans un magasin de clés, utilisez (RSAPublicKey)cert.getPublicKey(): cet objet a deux accesseurs pour le module et l'exposant.

Si c'est dans le format ci-dessus, vous pouvez utiliser BouncyCastle et sa PEMReader pour le lire. Je n'ai pas essayé le code suivant, mais cela ressemblerait plus ou moins à ceci:

PEMReader pemReader = new PEMReader(new FileReader("file.pem"));
Object obj = pemReader.readObject();
pemReader.close();
if (obj instanceof X509Certificate) {
   // Just in case your file contains in fact an X.509 certificate,
   // useless otherwise.
   obj = ((X509Certificate)obj).getPublicKey();
}
if (obj instanceof RSAPublicKey) {
   // ... use the getters to get the BigIntegers.
}

(Vous pouvez également utiliser BouncyCastle de la même manière en C #.)

88
Bruno

Faites attention au premier 00 qui peut apparaître dans le module lorsque vous utilisez: 

openssl rsa -pubin -inform PEM -text -noout < public.key

Le module d'exemple contient 257 octets au lieu de 256 en raison de ce 00, qui est inclus car le 9 sur 98 ressemble à un nombre signé négatif.

22
Rob

Si vous devez analyser des objets ASN.1 dans un script, il existe une bibliothèque pour cela: https://github.com/lapo-luchini/asn1js

Pour faire le calcul, j’ai trouvé jsbn commode: http://www-cs-students.stanford.edu/~tjw/jsbn/

Parcourir la structure ASN.1 et extraire exp/mod/subject/etc. à vous de choisir - je n’ai jamais été aussi loin!

1
Jonathan