RSA: Get exponent and modulus given a public key

Muszę zaszyfrować niektóre dane za pomocą RSA w JavaScript. Wszystkie biblioteki wokół pytają o wykładnik i moduł, jednak dostaję jeden plik public.key od mojego przeciwnika.

Jak odzyskać część publiczną exponent i modulus z pliku RSA?

Author: scottyab, 2010-06-25

5 answers

To zależy od narzędzi, których możesz użyć. Wątpię, że istnieje również JavaScript, który mógłby to zrobić bezpośrednio w przeglądarce. Zależy też, czy jest to jednorazowy (zawsze ten sam klucz), czy trzeba go skryptować.

Command-line / OpenSSL

Jeśli chcesz użyć czegoś takiego jak OpenSSL w uniksowej linii poleceń, możesz zrobić coś w następujący sposób. Zakładam, że jesteś publicznie.plik klucza zawiera coś takiego:

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

Wtedy komendy be:

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

Wtedy możesz zajrzeć do ASN.1 Struktura:

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

To powinno dać ci coś takiego:

    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 

Moduł i wykładnik publiczny są w ostatnim ciągu bitowym, przesunięcie 19, więc użyj -strparse:

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

To da ci moduł i wykładnik publiczny, w systemie szesnastkowym (dwie liczby całkowite):

    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

To prawdopodobnie w porządku, jeśli to zawsze ten sam klucz, ale prawdopodobnie nie jest to zbyt wygodne, aby umieścić w scenariusz.

Alternatywnie (a to może być łatwiejsze do umieszczenia w skrypcie),

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

Zwróci to:

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

To zależy od formatu wejściowego. Jeśli jest to certyfikat X. 509 w drzewie kluczy, użyj (RSAPublicKey)cert.getPublicKey(): Ten obiekt ma dwa gettery dla modułu i wykładnika.

Jeśli jest w formacie jak powyżej, możesz użyć BouncyCastle i jego PEMReader, aby go odczytać. Nie próbowałem poniższego kodu, ale wyglądałoby to mniej więcej tak Tak:

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

(możesz używać BouncyCastle podobnie w C#.)

 85
Author: Bruno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-12 15:53:40

Uważaj na wiodące 00, które mogą pojawić się w module podczas używania:

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

Przykładowy moduł zawiera 257 bajtów zamiast 256 bajtów z powodu tego 00, który jest uwzględniony, ponieważ 9 w 98 wygląda jak ujemna liczba podpisana.

 21
Author: Rob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-24 22:35:36

Jeśli chcesz parsować ASN.1 obiekty w skrypcie, jest do tego biblioteka: https://github.com/lapo-luchini/asn1js

Do robienia matematyki uznałem jsbn za wygodny: http://www-cs-students.stanford.edu/ ~ tjw / jsbn /

Chodzenie po ASN.1 Struktura i wyodrębnienie exp / mod/subject / etc. to zależy od ciebie ... nigdy nie zaszedłem tak daleko!

 1
Author: Jonathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 03:28:35

Głównie dla mojego własnego odniesienia, oto jak można go uzyskać z klucza prywatnego generowanego przez ssh-keygen

openssl rsa -text -noout -in ~/.ssh/id_rsa

Oczywiście działa to tylko z kluczem prywatnym.

 0
Author: user8513941,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-30 03:54:25

Oprócz powyższych odpowiedzi, możemy użyć asn1parse, aby uzyskać wartości

$ openssl asn1parse -i -in pub0.der -inform DER -offset 24
0:d=0  hl=4 l= 266 cons: SEQUENCE
4:d=1  hl=4 l= 257 prim:  INTEGER           :C9131430CCE9C42F659623BDC73A783029A23E4BA3FAF74FE3CF452F9DA9DAF29D6F46556E423FB02610BC4F84E19F87333EAD0BB3B390A3EFA7FB392E935065D80A27589A21CA051FA226195216D8A39F151BD0334965551744566AD3DAEB53EBA27783AE08BAAACA406C27ED8BE614518C8CD7D14BBE7AFEBE1D8D03374DAE7B7564CF1182A7B3BA115CD9416AB899C5803388EE66FA3676750A77AC870EDA027DC95E57B9B4E864A3C98F1BA99A4726C085178EA8FC6C549BE5EDF970CCB8D8F9AEDEE3F5CFDE574327D05ED04060B2525FB6711F1D78254FF59089199892A9ECC7D4E4950E0CD2246E1E613889722D73DB56B24E57F3943E11520776BC4F
265:d=1  hl=2 l= 3 prim:  INTEGER           :010001

Teraz, aby przejść do tego offsetu, próbujemy domyślnego asn1parse

$ openssl asn1parse -i -in pub0.der -inform DER
 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

Musimy dostać się do części ciągu bitowego, więc dodajemy rozmiary

depth_0_header(4) + depth_1_full_size(2 + 13) + Container_1_EOC_bit + BIT_STRING_header(4) = 24

To może być lepiej widoczne w: ASN.1 Parser, Jeśli najedziesz na znaczniki, zobaczysz offsety

Kolejny niesamowity zasób: ASN Microsoftu.1 Docs

 0
Author: pikaynu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-02 22:56:13