или же

я естьCertificates.p12 файл, который я хочу преобразовать вcertificates.pem содержащий незашифрованный закрытый ключ в формате PKCS # 1. Ранее я мог сделать это, запустив:

openssl pkcs12 -in Certificates.p12 -out certificates.pem -nodes -clcerts

Результирующийcertificates.pem файл имеетPRIVATE KEY Блок PEM, как и ожидалось. Тем не мение,библиотека, которую я использую не понимает этот блок PEM, потому что ожидает, что он будет закрытым ключом PKCS # 1. Структура ASN.1 закрытого ключа PKCS # 1 определяетсяRFC 3447 как:

RSAPrivateKey ::= SEQUENCE {
    version           Version,
    modulus           INTEGER,  -- n
    publicExponent    INTEGER,  -- e
    privateExponent   INTEGER,  -- d
    prime1            INTEGER,  -- p
    prime2            INTEGER,  -- q
    exponent1         INTEGER,  -- d mod (p-1)
    exponent2         INTEGER,  -- d mod (q-1)
    coefficient       INTEGER,  -- (inverse of q) mod p
    otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

Плохой блок закрытых ключей в моемcertificates.pem не имеет этой структуры PKCS # 1! Вместо этого его структура ASN.1 выглядит следующим образом:

$ openssl asn1parse -i -in badprivatekey.pem
    0:d=0  hl=4 l=1212 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim:  INTEGER           :00
    7:d=1  hl=2 l=  13 cons:  SEQUENCE
    9:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
   20:d=2  hl=2 l=   0 prim:   NULL
   22:d=1  hl=4 l=1190 prim:  OCTET STRING      [HEX DUMP]:308204A...very long hex...

Какой формат выше?Документация дляopenssl pkcs12 только смутно говорит, что его вывод «записан в формате PEM». Мне нужна более надежная гарантия того, что блок PEM закрытого ключа имеет формат PKCS # 1.

Странно то, чтоopenssl rsa понимает странный формат «плохого» закрытого ключа и может преобразовать его в правильную структуру PKCS # 1 с помощью:

openssl rsa -in badprivatekey.pem -out goodprivatekey.pem

Несмотря на то чтоopenssl rsa понимает входной файл, инструмент, кажется, не в состоянии сказать мнеПочемуто есть каков формат входного файла.

Каков выходной форматopenssl pkcs12? В частности, каков формат блока закрытого ключа? Как мне сделатьopenssl pkcs12 вывести правильный закрытый ключ PKCS # 1?

 jww04 дек. 2017 г., 16:59
Stack Overflow - сайт для вопросов программирования и разработки. Этот вопрос кажется не по теме, потому что он не касается программирования или разработки. ВидетьКакие темы я могу задать здесь в справочном центре. возможноСупер пользователь или жеUnix & Linux Stack Exchange было бы лучше спросить.
 lockcmpxchg8b02 дек. 2017 г., 05:37
Ответ dave_thompson_085 хороший. Я отвечу на ваш последний вопрос: выводopenssl pkcs12 похоже на PKCS # 8, по структуре, которую вы показываете выше. См. Запись модуля ASN.1 дляOneAsymmetricKey tools.ietf.org/html/rfc5958, В этой структуре версия отображается на ваш INTEGER 0, параметры отображаются на ваш NULL. Следовательно, как говорится в ответе dave_thompson_085, необходимая вам структура закрытого ключа RSA PKCS # 1 находится в строке OCTET STRING в вашем выводе. (Подсказка: начальный 0x30 является контрольным маркером того, что контент может быть дополнительным контентом ASN.1 ... это тег для SEQUENCE).

Ответы на вопрос(1)

Решение Вопроса

PRIVATE KEY должен быть PKCS1 ?? Это ужасно неправильно. Естьнесколько xx PRIVATE KEY форматы и толькоодин из них PKCS1, см. ниже.

Мета: ядумать это обман, но я не могу его найти, так что отвечаю в любом случае.

OpenSSL поддерживает ЧЕТЫРЕ различных формата PEM для закрытых ключей RSA:

«традиционный» или «устаревший» незашифрованный формат, который вам нужен (https://tools.ietf.org/html/rfc8017#appendix-A.1.2) с типом PEMRSA PRIVATE KEY (Не простоPRIVATE KEY)

«традиционный» или «устаревший», зашифрованный на уровне PEM с помощью пользовательской схемы OpenSSL (SSLeay), в которой используется довольно плохой (и нефиксируемый) PBKDF; это тот же тип PEMRSA PRIVATE KEY но добавил заголовкиProc-type а такжеDEK-info

PKCS8 стандартный / общий незашифрованный (https://tools.ietf.org/html/rfc5208#section-5) с типом PEMPRIVATE KEY; это простая оболочка ASN.1, содержащая идентификатор для алгоритма (то есть OID для RSA) плюс строку OCTET, содержащую зависимую от алгоритма часть, которая для RSA является PKCS1

PKCS8 стандартный / общий зашифрованный (https://tools.ietf.org/html/rfc5208#section-6) с типом PEMENCRYPTED PRIVATE KEY; это шифрует данные PKCS8 в ASN.1 с помощью алгоритма, который по умолчанию обычно равен, по крайней мере, PBKDF2-SHA1-2048, что является приемлемым

Поскольку PKCS8 является более гибким, стандартным (и довольно часто используемым, например, Java), и имеет лучшее шифрование, оно обычно является предпочтительным; см. раздел «Примечания»справочная страница для функций PEM_read / write для клавиш и некоторых, но не всех других вещей.

Все функции OpenSSL, которые читают закрытый ключ PEM, могут читать любые из них (при необходимости вводя правильный пароль), но которые они пишут, различаются в зависимости от функции и параметров экстента. Как вы заметилиpkcs12 (import) (в настоящее время) пишет PKCS8, ноrsa (всегда) пишет традиционный / PKCS1.

Ваши варианты:

использованиеrsa (как вы сделали), или в 1.1.0pkey -traditional, чтобы преобразовать в традиционные

использованиеpkcs12 в выпуске до 1.0.0, например 0.9.8, когда он писал традиционные форматы (для нескольких алгоритмов, а не только для RSA). Конечно, использование устаревшего и неподдерживаемого выпуска может привести к недостаткам и даже уязвимостям, которые были исправлены в более поздних выпусках.

извлечь часть PKCS1 из (незашифрованного или расшифрованного) PKCS8. OpenSSL использует DER для ключей, что означает, что зависимый от алгоритма большой двоичный объект, который является значением последнего поля в последней группе, всегда является непрерывной последней частью данных. В качестве примера:

$ openssl pkcs12 -in SO47599544.p12 -passin pass:sekrit -nocerts -nodes MAC verified OK Bag Attributes friendlyName: mykey localKeyID: 54 69 6D 65 20 31 35 31 32 31 37 30 38 39 39 33 33 37 Key Attributes: -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCnWIGH4p1FHOP2 wtVbxuyvSHpBGd2v+7AyVHG4EJ/9WRoWN4+aGYUOGxzdTyDxk9e7DCTjuY6ciNTh Ph74LADfQQ0B8yGkRtKer3vO1Dg7+6ErCcIGgsfrhZqpuUfod4nSU/LnHXoAAgN5 07LVvohrJMSRTA55jn356EDv31sz/dew1ThzHjYTShGbXh0/baqLxpmm4e8OixAL YV1glHnIdr4h6wrwkJ6TtNexc3xTLwtRf9k7pJPvg+viGh7RTqhbUcGSV+dLelNe 653LbElHtAByz4Ti9e4vUKFuzxqsaWaSYGpzxF/pdthQawV/fTa9CjLGJFFrnVqc KT3TSJ19AgMBAAECggEAOmmubRwxAVrgR9YiW3LIUzbdVbQNqcwU6LyJJVLIRcrA TFkAiy21QAM+xBFG0oxklSncBpFSslkg1a61aLMTatpuC+wuJgWCp1lhwgRZzLY8 v6UcUOF9nzx3jB7cdsyjEwOymfG0ECSjyfaXSfzD6YJgCsedldijKIRlhlVUpIS4 YvdPPGQMXxLr9K8dkQ9o5yTQCrpey1/dNEo7lS17/uMV++dxmka5J+/dRcm2AAIc 7dk6OX9MpGKPFODUyvFjdrWPR2qK25cmVW6hrhJuaPih+1eSd78UkR7OdoHBQEbJ 5MoXSO0eTV4rhid+dX+ynwXA2OvaZbxcr7rlZXjaAQKBgQDybaKW32RHVmjKQDXC xyTdQTMJV7JClBKeXjqJxbgKDhKFTiapn7kNVbJ594n7twuxmTxxoN35gamsbe7q HjEesZZvb2vgLTXnqSvSXcl32CEi554VjlNP6+jZ5JBu/Gw7qObKuWBt+/gkrtCx d09xQllZlD354RyfS3+9jzdEXQKBgQCwttL+Gw2WEm4dPQrfxbasXKQ5hNSE42j+ i0W26xv8o1lKQFip0A4YWidfI+Cvued944ZqCTvnPv6Z+JQzidHFjg6DXWgs1GK/ olsh5xO0hoxAj1azx+11ZHKSb7Kni+jSJsz40U35mWE805HFijxzzQz45unuPZGr d8oqXIcroQKBgQCKuU32w7JgWAPy6DdbVBW2Pl70E6jADHdzBDy/JdMgfdj/Sy84 lVuRU96jiJD+50nbwPIjm4gqBJaRQv8aHVjCVaDd94Zla7mS7O1UnbJxz812ac++ SglGjJpcRTyZJfzRTt9yVg3mIe9nHlnxk3J0PyFd70Rfvv9f8BYS5OcdSQKBgBnb xug0ITrSm5ZftlWkYuS58bYQ/+AqPtTwoFTx9nhzlr9MxyyiK03Y82XypBBSzdMY FjUyALgH+c2iGF2qTy3vaaRDaNkWgxSzt04wuCt0fNV9pBxOpyrEdheDjMsDqCAI WXoXdqeNkDMMaopTfiEb4kgR0i1wiP5kWwrz2zvBAoGBAPELu0IH3jtvo849KeXW O6U1QlxdmWS6h/La1iVRHoE2U3pxAj39IDx4P6GMrgc9VLqRKLTO1Cu9giimO2jH 8iryT5VTlrrINL3M4vXAFjSN/xwVsrLaw/mAQPOKBwNlDwxcCrlxnANnYXdrhk8n uNmZ2VH8flBFRpSbm9aisgMr -----END PRIVATE KEY----- $ openssl pkcs12 -in SO47599544.p12 -passin pass:sekrit -nocerts -nodes \ | sed -e 1,/-BEGIN/d -e /-END/,\$d | openssl asn1parse MAC verified OK 0:d=0 hl=4 l=1214 cons: SEQUENCE 4:d=1 hl=2 l= 1 prim: INTEGER :00 7:d=1 hl=2 l= 13 cons: SEQUENCE 9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption 20:d=2 hl=2 l= 0 prim: NULL 22:d=1 hl=4 l=1192 prim: OCTET STRING [HEX DUMP]:308204A4[rest snipped] [that's PKCS8 with algo-dependent part in the OCTET STRING at offset 22] [with a tag-length header length of 4 (the hl=4)]

Вы можете извлечь часть PKCS1 используяasn1parse -strparse: $ openssl pkcs12 -in SO47599544.p12 -passin pass:sekrit -nocerts -nodes \ | sed -e 1,/-BEGIN/d -e /-END/,\$d \ | openssl asn1parse -strparse 22 -out SO47599544.raw -noout MAC verified OK $ openssl asn1parse -in SO47599544.raw -inform der 0:d=0 hl=4 l=1188 cons: SEQUENCE 4:d=1 hl=2 l= 1 prim: INTEGER :00 7:d=1 hl=4 l= 257 prim: INTEGER :[snipped] 268:d=1 hl=2 l= 3 prim: INTEGER :010001 273:d=1 hl=4 l= 256 prim: INTEGER :[snipped] [rest snipped -- that's your PKCS1 format but in der so convert to pem] $ (echo -----BEGIN RSA PRIVATE KEY-----; openssl base64 -in SO47599544.raw; \ echo -----END RSA PRIVATE KEY-----) | tee SO47599544.pem -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAp1iBh+KdRRzj9sLVW8bsr0h6QRndr/uwMlRxuBCf/VkaFjeP mhmFDhsc3U8g8ZPXuwwk47mOnIjU4T4e+CwA30ENAfMhpEbSnq97ztQ4O/uhKwnC BoLH64WaqblH6HeJ0lPy5x16AAIDedOy1b6IayTEkUwOeY59+ehA799bM/3XsNU4 cx42E0oRm14dP22qi8aZpuHvDosQC2FdYJR5yHa+IesK8JCek7TXsXN8Uy8LUX/Z O6ST74Pr4hoe0U6oW1HBklfnS3pTXuudy2xJR7QAcs+E4vXuL1Chbs8arGlmkmBq c8Rf6XbYUGsFf302vQoyxiRRa51anCk900idfQIDAQABAoIBADpprm0cMQFa4EfW IltyyFM23VW0DanMFOi8iSVSyEXKwExZAIsttUADPsQRRtKMZJUp3AaRUrJZINWu tWizE2rabgvsLiYFgqdZYcIEWcy2PL+lHFDhfZ88d4we3HbMoxMDspnxtBAko8n2 l0n8w+mCYArHnZXYoyiEZYZVVKSEuGL3TzxkDF8S6/SvHZEPaOck0Aq6Xstf3TRK O5Ute/7jFfvncZpGuSfv3UXJtgACHO3ZOjl/TKRijxTg1MrxY3a1j0dqituXJlVu oa4Sbmj4oftXkne/FJEeznaBwUBGyeTKF0jtHk1eK4YnfnV/sp8FwNjr2mW8XK+6 5WV42gECgYEA8m2ilt9kR1ZoykA1wsck3UEzCVeyQpQSnl46icW4Cg4ShU4mqZ+5 DVWyefeJ+7cLsZk8caDd+YGprG3u6h4xHrGWb29r4C0156kr0l3Jd9ghIueeFY5T T+vo2eSQbvxsO6jmyrlgbfv4JK7QsXdPcUJZWZQ9+eEcn0t/vY83RF0CgYEAsLbS /hsNlhJuHT0K38W2rFykOYTUhONo/otFtusb/KNZSkBYqdAOGFonXyPgr7nnfeOG agk75z7+mfiUM4nRxY4Og11oLNRiv6JbIecTtIaMQI9Ws8ftdWRykm+yp4vo0ibM +NFN+ZlhPNORxYo8c80M+Obp7j2Rq3fKKlyHK6ECgYEAirlN9sOyYFgD8ug3W1QV tj5e9BOowAx3cwQ8vyXTIH3Y/0svOJVbkVPeo4iQ/udJ28DyI5uIKgSWkUL/Gh1Y wlWg3feGZWu5kuztVJ2ycc/NdmnPvkoJRoyaXEU8mSX80U7fclYN5iHvZx5Z8ZNy dD8hXe9EX77/X/AWEuTnHUkCgYAZ28boNCE60puWX7ZVpGLkufG2EP/gKj7U8KBU 8fZ4c5a/TMcsoitN2PNl8qQQUs3TGBY1MgC4B/nNohhdqk8t72mkQ2jZFoMUs7dO MLgrdHzVfaQcTqcqxHYXg4zLA6ggCFl6F3anjZAzDGqKU34hG+JIEdItcIj+ZFsK 89s7wQKBgQDxC7tCB947b6POPSnl1julNUJcXZlkuofy2tYlUR6BNlN6cQI9/SA8 eD+hjK4HPVS6kSi0ztQrvYIopjtox/Iq8k+VU5a6yDS9zOL1wBY0jf8cFbKy2sP5 gEDzigcDZQ8MXAq5cZwDZ2F3a4ZPJ7jZmdlR/H5QRUaUm5vWorIDKw== -----END RSA PRIVATE KEY-----

Или вы можете преобразовать тело PKCS8 в двоичный файл и просто отбросить первые 22 + 4 = 26 байтов (поскольку заголовок len hl = 4 из первого asn1parse выше):$ openssl pkcs12 -in SO47599544.p12 -passin pass:sekrit -nocerts -nodes \ | sed -e 1,/-BEGIN/d -e /-END/,\$d \ | openssl base64 -d | dd bs=1 skip=26 >SO47599544.raw MAC verified OK 1192+0 records in 1192+0 records out 1192 bytes (1.2 kB) copied, 0.00892462 s, 134 kB/s [then convert to PEM with echo BEGIN;base64(encode);echo END as above]

PS: Если важно прочитать PKCS12 только один раз, например, чтобы избежать повторного ввода пароля, вы можете использовать awk как

openssl pkcs12 -in file.p12 | \
awk '/BEGIN PRIVATE/,/END PRIVATE/{t=t $0 RS;next}1; \
  END{process t as the whole PRIVATE KEY PEM}'

или же

openssl pkcs12 -in file.p12 | \
awk '/BEGIN PRIVATE/{f=1;next}/END PRIVATE/{f=0;next}f{t=t $0 RS;next}1; \
    END{process t as just the base64 body}'

Ваш ответ на вопрос