Экспортировать файл PKCS # 12 без пароля для экспорта?

Я собираюсь экспортировать некоторые файлы pkcs # 12 для тестирования. Эти файлы не используются в производстве и существуют только во время автоматического тестирования.

Я использую следующую команду:

openssl pkcs12 -export -nodes -out bundle.pfx -inkey mykey.key -in certificate.crt -certfile ca-cert.crt

Почему он настаивает на пароле экспорта, когда я включил -nodes?

Моя версия OpenSSL OpenSSL 1.0.1f 6 Jan 2014 на 64-битном сервере Ubuntu Server.

Ответ 1

В интерактивном режиме, когда он запрашивает пароль, просто нажмите Enter, и пароль не будет установлен.

Если вы хотите автоматизировать это (например, в качестве команды -passout), используйте аргумент -passout. Ожидается, что параметр будет в форме pass:mypassword. Поскольку мы не хотим пароль:

openssl pkcs12 -export -nodes -out bundle.pfx -inkey mykey.key \
    -in certificate.crt -certfile ca-cert.crt \
    -passout pass:

Ответ 2

tl; dr То, что вы пытаетесь сделать, просто невозможно сделать с помощью утилиты командной строки OpenSSL. Это можно сделать только программно, используя libcrypto, криптографическую библиотеку OpenSSL.

Подробный ответ:

-nodes означает "не шифровать закрытый ключ", но в файле PKCS # 12 сертификаты также зашифрованы, поэтому даже с -nodes вам потребуется пароль для экспорта.

Смотрите документацию -descert которой говорится:

Зашифруйте сертификат с помощью тройного DES; это может сделать файл PKCS # 12 нечитаемым для некоторого программного обеспечения "степени экспорта". По умолчанию закрытый ключ шифруется с использованием тройного DES, а сертификат - с помощью 40-битного RC2.

Поэтому, если вы не используете эту опцию, сертификаты шифруются с использованием RC2. Вы можете изменить алгоритмы для ключа или сертификата, используя опции -keypbe и -certpbe.

Также для openssl pkcs12 опция -nodes указана только в разделе:

Варианты синтаксического анализа файла PKCS12:

Но вы не анализируете такой файл, вы создаете его, и если вы посмотрите на

Варианты создания файла PKCS12:

опция -nodes даже не указана.

Простое нажатие клавиши return при запросе пароля также не означает "нет пароля", но означает "пустой пароль" (ваш пароль - пустая строка), что является законным. Причина того, что в некоторых случаях это работает как отсутствие пароля, заключается в том, что некоторое программное обеспечение будет пытаться сначала прочитать файлы PKCS # 12 с пустым строковым паролем и только в случае сбоя запросит у пользователя действительный пароль, поэтому, если пароль пуст, в этих случаях пользователю никогда не будет предложено создать видимость, что "пароль не установлен".

Это может вызвать проблемы в macOS и iOS, так как Apple предполагает, что PKCS # 12 всегда имеет установленный пароль и не позволяет вам вводить "пустой пароль", поэтому, если файл имеет пустой набор пароля, импортировать его невозможно это на этих системах. Firefox также имел эту проблему в самом начале, но она была исправлена 13 лет назад.

При чтении файла PKCS # 12 сам OpenSSL пытается различить "нет пароля" и "пустой пароль" только путем предположения. Вот оригинальный код проекта:

 /* If we enter empty password try no password first */
 if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
     /* If mac and crypto pass the same set it to NULL too */
     if(!twopass) cpass = NULL;
 } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
     BIO_printf (bio_err, "Mac verify error: invalid password?\n");
     ERR_print_errors (bio_err);
     goto end;
 }

Первый раз, когда NULL передается для пароля, второй раз, когда пустая строка анализируется для пароля. Теперь давайте посмотрим на код при создании файла P12:

 p12 = PKCS12_create(cpass, name, key, ucert, certs,
             key_pbe, cert_pbe, iter, -1, keytype);

Теоретически этот вызов создаст файл PKCS # 12 без пароля, если и только если cpass равен NULL, однако, когда этот вызов выполняется, он не может быть равен NULL потому что если вы следуете по пути кода от начала функции до звоните выше, нет никакого кода пути, который приведет к cpass быть NULL в конце концов.

 if(!cpass) {
     if(export_cert) cpass = passout;
     else cpass = passin;
 }

 if(cpass) {
   mpass = cpass;
   noprompt = 1;
 } else {
   cpass = pass;
   mpass = macpass;
 }

В случае, если cpass был все еще NULL последним, if, это будет установлено, чтобы pass и pass:

char pass[50], macpass[50];

Это статическая статическая переменная, и при сохранении в указатель этот указатель не может быть NULL. Нет другого кода, который когда-либо cpass бы другое значение для cpass, поэтому cpass может быть пустой строкой, но это, конечно, не может быть NULL и, следовательно, нет файла PKCS # 12, который OpenSSL будет когда-либо создавать в командной строке без пароля. У него может быть пустой пароль, но у него наверняка есть пароль.