openssl - generar - RSA: Obtener exponente y módulo dado una clave pública
openssl linux (5)
Necesito cifrar algunos datos usando RSA en JavaScript. Todas las bibliotecas alrededor piden un exponente y un módulo, sin embargo, recibo un solo archivo public.key
de mi oponente.
¿Cómo recuperas la parte de modulus
y exponent
público de un archivo RSA?
Aparte de las respuestas anteriores, podemos usar asn1parse
para obtener los valores
$ 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
Ahora, para llegar a este desplazamiento, intentamos el asn1parse predeterminado
$ 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
Necesitamos llegar a la parte de la cadena BIT, así que agregamos los tamaños
depth_0_header(4) + depth_1_full_size(2 + 13) + Container_1_EOC_bit + BIT_STRING_header(4) = 24
Esto se puede visualizar mejor en: ASN.1 Parser , si pasa el cursor sobre las etiquetas, verá las compensaciones.
Otro recurso sorprendente: los documentos ASN.1 de Microsoft
Depende de las herramientas que puedas usar. Dudo que también haya un JavaScript que pueda hacerlo directamente dentro del navegador. También depende de si se trata de una sola vez (siempre la misma clave) o si necesita un script.
Línea de comandos / OpenSSL
Si desea utilizar algo como OpenSSL en una línea de comandos de Unix, puede hacer algo de la siguiente manera. Supongo que el archivo public.key contiene algo como esto:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmBAjFv+29CaiQqYZIw4P
J0q5Qz2gS7kbGleS3ai8Xbhu5n8PLomldxbRz0RpdCuxqd1yvaicqpDKe/TT09sR
mL1h8Sx3Qa3EQmqI0TcEEqk27Ak0DTFxuVrq7c5hHB5fbJ4o7iEq5MYfdSl4pZax
UxdNv4jRElymdap8/iOo3SU1RsaK6y7kox1/tm2cfWZZhMlRFYJnpoXpyNYrp+Yo
CNKxmZJnMsS698kaFjDlyznLlihwMroY0mQvdD7dCeBoVlfPUGPAlamwWyqtIU+9
5xVkSp3kxcNcNb/mePSKQIPafQ1sAmBKPwycA/1I5nLzDVuQa95ZWMn0JkphtFIh
HQIDAQAB
-----END PUBLIC KEY-----
Entonces, los comandos serían:
PUBKEY=`grep -v -- ----- public.key | tr -d ''/n''`
Entonces, puedes mirar en la estructura ASN.1:
echo $PUBKEY | base64 -d | openssl asn1parse -inform DER -i
Esto debería darle algo como esto:
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
El módulo y el exponente público están en la última BIT STRING, offset 19, así que usa -strparse
:
echo $PUBKEY | base64 -d | openssl asn1parse -inform DER -i -strparse 19
Esto le dará el módulo y el exponente público, en hexadecimal (los dos INTEGER):
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
Probablemente esté bien si siempre es la misma clave, pero probablemente no sea muy conveniente colocar un script.
Alternativamente (y esto podría ser más fácil de poner en un script),
openssl rsa -pubin -inform PEM -text -noout < public.key
devolverá esto:
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
Depende del formato de entrada. Si se trata de un certificado X.509 en un almacén de claves, use (RSAPublicKey)cert.getPublicKey()
: este objeto tiene dos captadores para el módulo y el exponente.
Si está en el formato anterior, puede usar BouncyCastle y su PEMReader
para leerlo. No he probado el siguiente código, pero esto se vería más o menos así:
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.
}
(También puedes usar BouncyCastle de manera similar en C #).
Principalmente para mi propia referencia, aquí le indicamos cómo puede obtenerlo de una clave privada generada por ssh-keygen
openssl rsa -text -noout -in ~/.ssh/id_rsa
Por supuesto, esto solo funciona con la clave privada.
Si necesita analizar objetos ASN.1 en el script, hay una biblioteca para eso: https://github.com/lapo-luchini/asn1js
Para hacer los cálculos, encontré jsbn conveniente: http://www-cs-students.stanford.edu/~tjw/jsbn/
Recorriendo la estructura ASN.1 y extrayendo exp / mod / subject / etc. depende de ti - nunca llegué tan lejos!
Tenga cuidado con los 00 iniciales que pueden aparecer en el módulo al usar:
openssl rsa -pubin -inform PEM -text -noout < public.key
El módulo de ejemplo contiene 257 bytes en lugar de 256 bytes debido a ese 00, que se incluye porque el 9 en 98 parece un número con signo negativo.