tl;dr 如果您将加密算法都明确设置为NONE(用于密钥的算法和用于证书的算法),您仍然需要提供密码,但没有执行加密时,您提供的密码无关紧要,因为密码会被忽略并且生成的文件未加密。
如需完整的命令行示例,请查看此回复:
https://stackoverflow.com/a/62863490/7878845
很详细的回答:
-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);
理论上,如果cpass 是NULL,则此调用将创建一个没有密码的PKCS#12 文件,但是,在进行此调用时,它不能是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最后还是NULLif,它将被设置为pass和pass是:
char pass[50], macpass[50];
这是一个静态变量,当存储到一个指针时,这个指针不能是NULL。没有其他代码会为cpass 分配不同的值,因此cpass 可以是空字符串,但它绝对不能是NULL。
实际加密发生在名为PKCS12_add_safe_ex() 的函数中,如果查看此函数,您会看到以下代码:
if (nid_safe == 0)
#ifdef OPENSSL_NO_RC2
nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
#else
nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
#endif
if (nid_safe == -1)
p7 = PKCS12_pack_p7data(bags);
else
p7 = PKCS12_pack_p7encdata_ex(nid_safe, pass, -1, NULL, 0, iter, bags, ctx, propq);
if (p7 == NULL)
goto err;
nid_safe 是一个数字,告诉函数使用哪种加密方法。如您所见,如果未设置(0 的值),则使用默认值,即 RC2,如果不可用,则使用 3DES。
但是,如果nid_safe 是-1,这意味着NONE,则正在使用替代函数并且pass 甚至没有传递给该函数,因此pass 的值完全不相关案子。因此,您可以提供任何您喜欢的密码,如果您将密钥和证书的加密算法设置为NONE,则不会加密任何内容。