导出没有导出密码的PKCS#12文件?

时间:2014-12-16 04:51:01

标签: openssl command pkcs#12

我正在生成导出一些pkcs#12文件以进行测试。这些文件未在生产中使用,仅在自动化测试期间临时存在。

我使用以下命令:

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

为什么在我加入-nodes后,它会坚持使用导出密码?

我的OpenSSL版本在64位Ubuntu Server 14.10上为OpenSSL 1.0.1f 6 Jan 2014

4 个答案:

答案 0 :(得分:53)

在交互模式下,当提示输入密码时,只需按回车键即可设置密码。

如果您想要自动化(例如作为ansible命令),请使用-passout参数。它希望参数的格式为pass:mypassword。因为我们不需要密码:

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

答案 1 :(得分:2)

要仅使用OpenSSL命令行实用程序生成未加密的PKCS12文件,请调用以下命令:

$ openssl pkcs12 -export -keypbe NONE -certpbe NONE -nomaciter -passout pass: -out bundle.pfx -inkey mykey.key -in certificate.crt -certfile ca-cert.crt

将私钥(-keypbe)和证书(-certpbe)的加密算法设置为NONE时,openssl的pkcs12库将忽略密码参数,并且不对私钥和证书进行加密。 / p>

这可以通过openssl pkcs12 -info命令进行验证:

$ openssl pkcs12 -info -in bundle.pfx -noout -passin pass:
MAC: sha1, Iteration 1
MAC length: 20, salt length: 8
PKCS7 Data
Certificate bag
Certificate bag
PKCS7 Data
Key bag

请注意,在使用openssl命令行工具读取现有PKCS12文件时,即使未加密数据也需要指定-passin pass:参数。这是因为openssl命令行工具无法检测PKCS12文件是否已加密。指定空密码后,openssl首先尝试读取未加密的文件。如果失败,则openssl尝试读取该文件,并使用空密码进行加密。

当我生成bundle.pfx而不指定-keypbe NONE -certpbe NONE -nomaciter自变量时,openssl pkcs12 -info显示如下:

$ openssl pkcs12 -info -in bundle.pfx -noout -passin pass:
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048

因此,在这种情况下,数据将使用空密码进行加密。

答案 2 :(得分:1)

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甚至都没有列出。

在提示您输入密码时,只要按回车键也不会表示“无密码”,而是表示“空密码”(您的密码为空字符串),这是合法的。在某些情况下,此操作就像没有密码一样起作用,原因是某些软件会尝试首先读取带有空字符串密码的PKCS#12文件,并且只有在失败的情况下,才提示用户输入实际密码,因此,如果密码为空,在这种情况下,永远不会提示用户,就好像没有设置密码。

这可能会在macOS和iOS中引起问题,因为Apple假定PKCS#12始终设置了密码,并且不允许您输入“空密码”,因此,如果文件设置了空密码,则为无法在这些系统上导入它。 Firefox最初也有此问题,但it was fixed 13 years ago

在读取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);

理论上,如果且仅当 cpassNULL时,此调用将创建不带密码的PKCS#12文件,但是,在进行此调用时,它将不能为NULL,因为如果您遵循从函数开头到上述调用的代码路径,则没有代码路径会导致cpass最终成为NULL。< / p>

 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可以为空字符串,但肯定不能为NULL,因此,OpenSSL不会提供PKCS#12文件曾经在命令行创建没有密码。它可能有一个空密码,但肯定有一个密码。

答案 3 :(得分:1)

需要为openconnect转换证书时遇到相同的问题

需要其他步骤才能使其不使用密码

openssl rsa -in private.key -out private.nopwd.key