2016-12-21 5 views
3

Существует ключ RSA из RFC:Как преобразовать открытый ключ из JWK в PEM для OpenSSL?

https://tools.ietf.org/html/rfc7516#appendix-A.1

{"kty":"RSA", 
    "n":"oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW 
     cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S 
     psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a 
     sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS 
     tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj 
     YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw", 
    "e":"AQAB", 
    "d":"kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N 
     WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9 
     3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk 
     qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl 
     t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd 
     VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ", 
    "p":"1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ- 
     SWxkbkmoEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lf 
     fNn03IXqWF5MDFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0", 
    "q":"wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBm 
     UDdaDYVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aX 
     IWxKwd4gvxFImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc", 
    "dp":"ZK-YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KL 
     hMXvo-uz-KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827 
     rnpZzAJKpdhWAgqrXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE", 
    "dq":"Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCj 
     ywcMlYYg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDB 
     UfCAiJVeESOjJDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis", 
    "qi":"VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8-ZW1FxU7 
     AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E3 
     eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY" 
} 

Я попытался jwk-to-pem:

https://stackoverflow.com/a/35995690/4742108

-----BEGIN RSA PUBLIC KEY----- 
MIIBCgKCAQEAoahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E+BVvxkeDNjbC4 
he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S 
psk/ZkoFnilakGygTwpZ3uesH+PFABNIUYpOiN15dsQRkgr0vEhxN92i2asbOenS 
ZeyaxziK72UwxrrKoExv6kc5twXTq4h+QChLOln0/mtUZwfsRaMStPs6mS6Xrgxn 
xbWhojf663tuEQueGC+FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR/MB/4NUJW/T 
qOQtwHYbxevoJArm+L5StowjzGy+/bq6GwIDAQAB 
-----END RSA PUBLIC KEY----- 

также заменить "RSA Public Key" с «PUBLIC KEY».

Команда openssl rsa -inform PEM -pubin дает:

unable to load Public Key 
139911798556312:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1197: 
139911798556312:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:374:Type=X509_ALGOR 
139911798556312:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:697:Field=algor, Type=X509_PUBKEY 
139911798556312:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_oth.c:83: 

Как получить полезный ключ?

+1

Чтобы прояснить одно, однако, что JWK содержит закрытый ключ. Каждый раз, когда вы видите «p», «q» или «d», ключ RSA включает частные параметры. – vcsjones

ответ

3

Таким образом, ключ, который вы разместили, представляет собой простую последовательность asn открытого ключа и общественного экспонента. Это выглядит примерно так:

SEQUENCE ::= { 
    n Integer, 
    e Integer 
} 

OpenSSL не так, как есть, потому что не хватает несколько других вещей, как ObjectIdenifier так, что OpenSSL знает, какой алгоритм ключ для.

Быстрый способ исправить это также положить в опции -RSAPublicKey_in, так что полная команда будет выглядеть примерно так:

openssl rsa -inform pem -in FILEPATH.pem -pubin -pubout -RSAPublicKey_in 

и изменить заголовок файла обратно включить «RSA»:

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

, а также сноска:

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

Это будет также OUTP внесите его в «обычный» формат открытого ключа, который включает в себя отсутствующий ObjectIdentifier.

Примечание: Я не уверен, что требуется для версии -RSAPublicKey_in, но я использовал OpenSSL 1.1.0.

3

Я разработал класс PHP, который способен преобразовывать общедоступные/частные ключи из JWK в PEM (и наоборот).

You will find that class here.

В принципе, вы должны декодировать каждый компонент из Base64UrlSafe в двоичную строку и собрать все из них в соответствии со структурой ASN.1, описанной в RFC3447.

Тем не менее, я рекомендую вам использовать специальную библиотеку/инструмент для облегчения вашей работы. С моей PHP библиотекой, ваш код будет выглядеть так:

use Jose\KeyConverter\RSAKey; 
$key = new RSAKey([ 
    "kty" => "RSA", 
    "n" => "oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3Spsk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2asbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMStPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw", 
    "e" => "AQAB", 
    "d" => "kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5NWV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD93Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghkqDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vlt3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSndVTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ", 
    "p" => "1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ-SWxkbkmoEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lffNn03IXqWF5MDFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0", 
    "q" => "wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBmUDdaDYVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aXIWxKwd4gvxFImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc", 
    "dp" => "ZK-YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KLhMXvo-uz-KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827rnpZzAJKpdhWAgqrXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE", 
    "dq" => "Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCjywcMlYYg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDBUfCAiJVeESOjJDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis", 
    "qi" => "VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8-ZW1FxU7AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E3eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY", 
]); 
$pem = $key->toPEM(); 
2

Я написал инструмент командной строки под названием lokey, чтобы помочь с ключевым преобразованием, как этот.

Использование curl, grep и tr, чтобы захватить ключ от вопроса, мы можем конвертировать JWK отформатирован закрытого ключа в PEM отформатированный секретный ключ с помощью этой команды:

$ curl -s https://tools.ietf.org/rfc/rfc7516.txt | grep '"n":"oahUI' -B1 -A28 | tr -d '[:space:]' | lokey to pem 

-----BEGIN RSA PRIVATE KEY----- 
MIIEowIBAAKCAQEAoahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E+BVvxkeDN 
jbC4he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2K 
rf3Spsk/ZkoFnilakGygTwpZ3uesH+PFABNIUYpOiN15dsQRkgr0vEhxN92i2asb 
OenSZeyaxziK72UwxrrKoExv6kc5twXTq4h+QChLOln0/mtUZwfsRaMStPs6mS6X 
rgxnxbWhojf663tuEQueGC+FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR/MB/4NU 
JW/TqOQtwHYbxevoJArm+L5StowjzGy+/bq6GwIDAQABAoIBAQCQt20iPoZsOSz8 
CkJJNhC16Vw222UqI7I/Mytcd4j7KTUXv6SkPFjj5Zjk1ZXkqe1oR5dLWPzYTfvn 
HGFYwdfK+Nh5w9P1+nBH8z2BXyf0euHZqdOlMP3cO3rbKlbfIOwnMGdOeti7WLBZ 
GAEqsRhjjqoBkisDbEDCebZfu4ZHWGCGSoOnRWqPeRtILPVfJ8Kzr8t6EHC3EcjK 
HxGKnLjSnbiag4BuDFXDevFP++W3dRV7hY7cmQk7OWlR/4pNUjY+2Cb50BHFMS0T 
6J37g4mvSH4r5UWzdVKd1VMjOdLF/KuPwgsvowb9S/xgC7tUgtIHeU5bTzn7ioTc 
POCtOODJAoGBANa+dl5OOnPi7HweT+ONqe2rXT1K8UEsuJrYv7WSNzIH9hLhVW1K 
Awb2kUPklsZG5JqBMy+yV66EgY0qyt2CEIGHTIMgBD0z417/4SNv9Xk0j1WX8y9J 
X3zZ9NyF6lheTAxbqFGBNIc29r4a5Tf6yq23wyMFG06444InkW8AugpdAoGBAMC2 
9+ce4ZkFmbFiZgf75XvO4oYGdfUvJQRETiyLGRuGsmVXvR4vYA1QjgZlA3Wg2FU0 
jcf/BcsNWGGvVxqxpw3sNNCdvHEVKHgQf4yiNaJmtDq79U/WlyFsSsHeIL8RSJjl 
q90ES/ShAUc5NkWrVAZ5g2SUyAH8E7NIOvFGR77XAoGAZK+YwE7diUh0qR1tR7w8 
WHtolDx3MZ/OTowiFvgfeQ3SiresXjm9gZ5KLhMXvo+uz+KUJWDxS5pFQ/M0evdo 
1dKiRTjVw/x4NyqyXPM5nULPkcpU827rnpZzAJKpdhWAgqrXGKAECQH0Xt4taznj 
nd/zVpAmZZq60WPMBMfKcuECgYAOrSB+AnUN0UZeIu9ARme4oQ3RRSawkHGSPJ1z 
ePhlh0GIxEDLzrHS8cKPLBwyVhiDjKgLhhlr2E1VyyOoDcV6IvX2uTyDpCfb1O3R 
yPyqrIWnP280MFR8ICIlV4RI6MkNk9gd0djy/Vv6j5nZfm28vH5MJ6R/ujHJ4oNS 
opaOKwKBgFSDKTGGz3+O3U9cP8w1F3z4prEnoJzDgNc02l+2hpP/Lq2OkfPmVtRc 
VOwJVgMi1sm6qurdelRXe4UHdMun5VCuEpTsnQetYMGpzrFxjgDr/NnB6tBN3i+B 
67WZFLir5z6zJ7FFBZX1Hcm1c8co8/SRf18mmNeGq3S0o3+C/xTW 
-----END RSA PRIVATE KEY----- 

Lokey также имеет команду fetch что могут быть использованы для извлечения ключей JWK из OpenID конечных точек:

$ lokey fetch jwk example.okta.com 
$ lokey fetch jwk login.salesforce.com 
$ lokey fetch jwk accounts.google.com 

Вы можете затем передать этот выход в lokey снова, чтобы получить PEM:

$ lokey fetch jwk example.okta.com | lokey to pem 
+0

Я получил эту ошибку Traceback (самый последний вызов последним): Файл "/ USR/местные/бен/Lokey", строка 7, в из Lokey импорта Cli Файл «/Library/Python/2.7/site- пакеты/Lokey/__ init__.py», строка 9, в импорта Эрис Файл "/Library/Python/2.7/site-packages/eris/__init__.py", строка 14, в от pgpy.constants импорта ( Файл «/Library/Python/2.7/site-packages/pgpy/__init__.py», строка 5, в из .pgp import PGPKey – hungneox

0

Я написал Swift library, который может преобразовывать общедоступные/закрытые ключи из JWK в кодировку PEM PKCS # 8.

Вы можете использовать его:

import JWKTransform 

let key = try RSAKey(jwk: token) 
let publicPem = try key.getPublicKey() 
let privatePem = try key.getPrivateKey() 

Что касается фактического JWK, поля RSA вы включены в виду следующее:

  • параметр n: URL кодировкой Base64 строку, представляющую modulus АСР Ключ.
  • параметр e: кодированная строка Base64, представляющая public exponent ключа RSA.
  • параметр d: Base64 URL-кодированная строка, представляющая private exponent ключа RSA.
  • параметр p: Base64 URL-кодированная строка, представляющая secret prime factor ключа RSA.
  • параметр q: Base64 URL-кодированная строка, представляющая secret prime factor ключа RSA.
  • параметр dp: Base64 URL-кодированная строка, представляющая first factor CRT exponent ключа RSA. d mod (p-1)
  • параметр dq: Base64 URL-кодированная строка, представляющая second factor CRT exponent ключа RSA. d mod (q-1)
  • параметр qi: Base64 URL-кодированная строка, представляющая first CRT coefficient ключа RSA. q^-1 mod p

Я включил рядом с каждым параметром соответствующее поле в структуре RSA OpenSSL. Это только в случае, если вы хотите иметь дело с OpenSSL напрямую :-)

Также отметит, что если сравнивать ключи, которые производятся с использованием ссылочных библиотек с OpenSSL-сгенерированными ключами RSA:

  • public key: Этих библиотека должна создать открытый ключ, который генерирует OpenSSL.

  • private key: Для закрытого ключа RSA требуется только q, но операции RSA, как правило, намного быстрее, когда предоставляются остальные значения выше. Открытые OpenSSL файлы ключей RSA включают эти значения.Поэтому, если не все частные параметры предоставлены, то полученный закрытый ключ может быть несовместим с исходным OpenSSL.

Смежные вопросы