Как я могу преобразовать два стиля формата открытого ключа, один формат:
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
другой формат:
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----
например, я сгенерировал пару id_rsa / id_rsa.pub с помощью команды ssh-keygen, я вычислил открытый ключ из id_rsa, используя:
openssl rsa -in id_rsa -pubout -out pub2
затем я снова вычислил открытый ключ из id_rsa.pub, используя:
ssh-keygen -f id_rsa.pub -e -m pem > pub1
содержание pub1:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----
а содержание pub2:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB
-----END PUBLIC KEY-----
Насколько я понимаю, pub1 и pub2 содержат одну и ту же информацию об открытом ключе, но они находятся в другом формате. Интересно, как я могу преобразовать эти два формата? Может ли кто-нибудь показать мне краткое введение в форматы буксировки?
Ответы:
Используя phpseclib, чистую реализацию PHP RSA ...
Похоже, что данные в кодировке base64 совпадают, даже если в заголовке написано BEGIN PUBLIC KEY, а не BEGIN RSA PUBLIC KEY. Так что, может быть, просто используйте str_replace, чтобы исправить это, и все будет хорошо!
источник
Я хотел помочь объяснить, что здесь происходит.
«Открытый ключ» RSA состоит из двух чисел:
Используя ваш открытый ключ RSA в качестве примера, два числа:
Тогда возникает вопрос, как мы хотим хранить эти числа в компьютере. Сначала мы конвертируем оба в шестнадцатеричный:
RSA изобрела первый формат
RSA первой изобрела формат:
Они решили использовать вариант DER стандарта двоичного кодирования ASN.1 для представления двух чисел [1] :
Окончательная двоичная кодировка в ASN.1:
Если вы затем запустите все эти байты вместе и закодируете их в Base64, вы получите:
Затем лаборатории RSA сказали добавить заголовок и трейлер:
Пять дефисов и слова
BEGIN RSA PUBLIC KEY
. Это ваш открытый ключ PEM DER ASN.1 PKCS # 1 RSAНе только RSA
После этого появились другие формы криптографии с открытым ключом:
Когда пришло время создать стандарт для представления параметров этих алгоритмов шифрования, люди взяли на вооружение многие идеи, изначально определенные RSA:
BEGIN PUBLIC KEY
Но вместо того, чтобы использовать:
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN DH PUBLIC KEY-----
-----BEGIN EC PUBLIC KEY-----
Вместо этого они решили включить идентификатор объекта (OID) того, что будет дальше. В случае открытого ключа RSA это:
1.2.840.113549.1.1.1
Итак, для открытого ключа RSA это было по существу:
Теперь они создали SubjectPublicKeyInfo, который в основном:
Фактическое определение DER ASN.1:
Это дает вам ASN.1 из:
Окончательная двоичная кодировка в ASN.1:
И, как и раньше, вы берете все эти байты, кодируете их в Base64, и вы получаете второй пример:
Добавьте немного другой заголовок и трейлер, и вы получите:
И это ваш открытый ключ X.509 SubjectPublicKeyInfo / OpenSSL PEM [2] .
Сделай это правильно или взломай
Теперь, когда вы знаете, что кодировка не является волшебной, вы можете написать все части, необходимые для анализа модуля и экспоненты RSA. Или вы можете узнать, что первые 24 байта просто добавлены новые вещи поверх исходного стандарта PKCS # 1.
Эти первые 24 байта - это «новый» материал:
И благодаря необычайному стечению обстоятельств удачи и удачи:
Потому что в Base64: 3 байта превращаются в четыре символа:
Это означает, что если вы возьмете второй открытый ключ X.509, первые 32 символа будут соответствовать только вновь добавленным материалам:
Если вы удалите первые 32 символа и измените его на BEGIN RSA PUBLIC KEY :
У вас есть именно то, что вы хотели - старый
RSA PUBLIC KEY
формат.источник
Я нашел этот веб-сайт хорошим техническим объяснением различных форматов: https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem
«BEGIN RSA PUBLIC KEY» - это PKCS # 1, который может содержать только ключи RSA.
«НАЧАТЬ ОТКРЫТЫЙ КЛЮЧ» - это PKCS # 8, который может содержать множество форматов.
Если вы просто хотите преобразовать их с помощью командной строки, для этого подойдет "openssl rsa".
Чтобы преобразовать PKCS # 8 в PKCS # 1:
Чтобы преобразовать PKCS # 1 в PKCS # 8:
источник
unknown option -RSAPublicKey_in
Хотя приведенные выше комментарии относительно 32-байтовых заголовков, форматов OID и тому подобного интересны, я лично не вижу такого поведения, если я понимаю суть. Я подумал, что было бы полезно изучить это подробнее, что, по мнению большинства, является чрезмерным. Ничто не превосходит крайности.
Для начала я создал закрытый ключ RSA и проверил его:
(О, ужасы! Я открыл секретный ключ. Ммм ...)
Я извлекаю и показываю его открытый ключ:
Так получилось, что есть еще один выходной параметр открытого ключа (как упоминалось в предыдущем комментарии). Вместо этого я извлекаю и отображаю открытый ключ, используя это ключевое слово:
Ну ну. Эти два значения открытого ключа не совпадают, хотя они получены из одного и того же закрытого ключа. Или они такие же? Я вырезаю и вставляю две строки открытого ключа в их собственные файлы, а затем проверяю модуль для каждой:
«Pubin» говорит ПДС , что это на самом деле это должен быть открытый ключ, и не жалуются , что это не закрытый ключ.
Теперь мы берем открытый ключ RSA, отображаем модуль и преобразуем его в простой старый «открытый ключ» (опять же, мы должны сказать ему, что ввод является открытым ключом):
Отображается тот же модуль и то же значение «открытого ключа». Чтобы сделать вещи более интересными (во всяком случае для меня), когда мы добавляем ключевое слово RSAPublicKey_out, мы получаем:
... и когда мы трансмогрифицируем простой старый `` открытый ключ '' в открытый ключ RSA:
... неумолимо идем вперед, и хотя мы сделали это всего несколько команд назад, чтобы придать смысл, мы перевернули все так, чтобы трансмогрификация происходила от RSA к обычному старому «общедоступному ключу»:
... что возвращает нас к тому, с чего мы начали. Что мы узнали?
Резюме: клавиши внутри такие же, только выглядят по-разному. В предыдущем комментарии указывалось, что формат ключа RSA был определен в PKCS # 1, а простой старый формат «открытого ключа» был определен в PKCS # 8. Однако редактирование одной формы не превращает ее в другую. Надеюсь, теперь я забил это различие до смерти.
Тем не менее, если еще осталась искра жизни, давайте еще немного рассмотрим сертификат, который был изначально сгенерирован с помощью закрытого ключа RSA так давно, исследуя его открытый ключ и модуль:
... и все они жили долго и счастливо: сертификат имеет то же значение модуля, что и открытый ключ RSA, закрытый ключ RSA и простой старый «открытый ключ». Сертификат содержит то же самое обычное старое значение «открытого ключа», которое мы видели ранее, хотя он был подписан файлом, помеченным как закрытый ключ RSA. Можно с уверенностью сказать, что есть консенсус.
В квадранте X509 галактики OpenSSL нет эквивалентного ключевого слова «RSAPublicKey_out», поэтому мы не можем попробовать это, хотя значение модуля описывается как «модуль ключа RSA», который, как я полагаю, максимально приближен к нам.
Я не знаю, как все это будет выглядеть с сертификатом, подписанным DSA.
Я понимаю, что это не отвечает на исходный вопрос, но, возможно, дает некоторые полезные сведения. Если нет, мои извинения. По крайней мере, то, что не следует делать, и предположения, которых не следует делать.
Несомненно, можно было заметить немного раздражающее повторение «записи ключа RSA», когда ничего подобного не происходит. Я предполагаю, что имеется в виду, что модуль rsa распознает простой старый открытый ключ как истинный ключ RSA, и поэтому он продолжает твердить о «ключ RSA» (плюс, в конце концов, это модуль rsa). Если я правильно помню, в общей структуре EVP_PKEY есть объединение для всех типов ключей, причем каждый тип ключа имеет свой собственный специальный набор значений (услужливо названные g, w, q и другие согласные).
В заключение отмечу, что была жалоба на программирование и разработку; Теперь каждая команда OpenSSL, очевидно, имеет соответствующий код, и если кто-то хочет исследовать все чудеса программирования OpenSSL сегодня, командная строка может показаться разумным местом для начала. В этом конкретном случае (поскольку я использую недавний cygwin) можно начать с просмотра \ openssl-1.0.2f \ apps \ rsa.c и (учитывая высокую устойчивость к макросам) \ openssl-1.0. 2f \ крипто \ pem \ pem_all.c
источник
Единственное различие между pub1 и pub2, кроме верхнего / нижнего колонтитула, эта дополнительная строка в pub2:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
. Если вы удалите это, Base 64 будет идентичен таковому в pub1.Дополнительная строка соответствует идентификатору алгоритма в соответствии с этим ответом .
источник