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

F21*_*F21 46 command openssl pkcs#12

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

我使用以下命令:

openssl pkcs12 -export -nodes -out bundle.pfx -inkey mykey.key -in certificate.crt -certfile ca-cert.crt
Run Code Online (Sandbox Code Playgroud)

我包含时为什么要坚持输出密码-nodes

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

F21*_*F21 62

在交互模式下,当提示输入密码时,只需按Enter键,就不会设置密码.

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

openssl pkcs12 -export -nodes -out bundle.pfx -inkey mykey.key \
    -in certificate.crt -certfile ca-cert.crt \
    -passout pass:
Run Code Online (Sandbox Code Playgroud)

  • 这会生成一个带有空字符串作为密码的文件,这与没有密码的情况不同.您仍然必须在密码提示符上按Enter键,这在iOS设备上不起作用,因为它们不允许您使用空字符串按Enter键. (30认同)
  • 使用-export时,-nodes甚至不是有效的参数,请参见手册页。两次击中return会设置一个空密码,这与没有密码不同。`-passout pass:`也设置一个空密码。我的回答通过查看代码证明,只有在直接使用libcrypto时,才能在命令行上创建没有密码的PKCS#12文件。@尼克是绝对正确的。 (2认同)

Pal*_*ali 13

要仅使用 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
Run Code Online (Sandbox Code Playgroud)

当私钥 ( -keypbe) 和证书 ( -certpbe) 的加密算法设置NONE为时,openssl 的 pkcs12 库会忽略密码参数并且不加密私钥和证书。

这可以通过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
Run Code Online (Sandbox Code Playgroud)

请注意,使用 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
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下数据是用空密码加密的。


Mec*_*cki 11

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也从一开始就存在此问题,但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;
 }
Run Code Online (Sandbox Code Playgroud)

第一次NULL传递密码,第二次解析空字符串作为密码。现在让我们看一下创建P12文件时的代码:

 p12 = PKCS12_create(cpass, name, key, ucert, certs,
             key_pbe, cert_pbe, iter, -1, keytype);
Run Code Online (Sandbox Code Playgroud)

从理论上讲,此调用将在以下情况下创建一个不带密码的PKCS#12文件:仅当 cpass是时NULL;但是,在进行此调用时,这不可能是NULL因为如果您遵循从函数开始到上面调用的代码路径,没有这将导致代码路径cpassNULL到底。

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

 if(cpass) {
   mpass = cpass;
   noprompt = 1;
 } else {
   cpass = pass;
   mpass = macpass;
 }
Run Code Online (Sandbox Code Playgroud)

如果cpass仍然NULL在最后if,它将设置为pass并且pass是:

char pass[50], macpass[50];
Run Code Online (Sandbox Code Playgroud)

这是一个静态静态变量,当存储到指针时,该指针不能为NULL。没有其他代码可以为分配不同的值cpass,因此cpass可以是一个空字符串,但一定不能为空字符串NULL,因此OpenSSL不会在命令行上创建没有密码的PKCS#12文件。它可能有一个空密码,但肯定有一个密码。

  • Mecki,仅使用 OpenSSL 命令行实用程序就可以生成未加密的 PKCS12 文件!有关详细信息,请参阅我的答案 /sf/answers/4400444331/。当“key_pbe”和“cert_pbe”都设置为“-1”时,传递给“PKCS12_create()”的变量“cpass”将被忽略,这可以通过命令行参数“NONE”来实现。 (3认同)