我正在生成导出一些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
。
答案 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);
理论上,如果且仅当 cpass
为NULL
时,此调用将创建不带密码的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