我有一个创建 .p12 文件的 Java 应用程序(使用 Bouncycastle (BC))。 我无法将通过 Java 创建的 .p12 文件导入 macOS (macos 11) 钥匙串:
security import mycert-personauth.p12 -k ~/Library/Keychains/login.keychain-db
提示输入密码,当我输入密码时失败“抱歉,您输入的密码无效”。 如果我使用与 openssl 相同的密码来查看文件,它可以正常工作:
openssl pkcs12 -in mycert-personauth.p12 -info -nokeys -passin pass:$pw
如果我从 mycert-personauth.p12 中的相同证书创建 p12,它就可以工作。
openssl pkcs12 -export -out ~/test1.pfx -inkey cert/mytest-personauth.key -in cert/mytest-personauth.crt -certfile ca/ca-trust.crt
security import ~/test1.pfx -k ~/Library/Keychains/login.keychain-db
[ GUI prompt for password here ]
1 identity imported.
2 certificates imported.
这是 openssl 报告的不工作的 mycert-personauth.p12(在带有 openssl 3.0.11 的 Linux 上运行):
MAC: sha256, Iteration 10000
MAC length: 32, salt length: 20
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Certificate bag
Bag Attributes
friendlyName: certandkey
localKeyID: 54 69 6D 65 20 31 37 31 37 37 31 30 30 32 33 39 38 31
subject=/DC=com/DC=contoso/CN=Users/CN=David Bowie
issuer=/DC=com/DC=contoso/CN=Contoso Issuing CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Certificate bag
Bag Attributes
friendlyName: CN=Contoso Issuing CA,DC=contoso,DC=com
subject=/DC=com/DC=contoso/CN=Contoso Issuing CA
issuer=/CN=Contoso Root CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Certificate bag
Bag Attributes
friendlyName: CN=Contoso Root CA
subject=/CN=Contoso Root CA
issuer=/CN=Contoso Root CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
这是成功导入的工作 test1.p12(openssl 在 macos 上运行):
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
localKeyID: F8 AB 55 96 23 95 4F 41 50 87 DB 98 41 DE 3A 78 50 66 2B 6D
subject=/DC=com/DC=contoso/CN=Users/CN=David Bowie
issuer=/DC=com/DC=contoso/CN=Contoso Issuing CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Certificate bag
Bag Attributes: <No Attributes>
subject=/DC=com/DC=contoso/CN=Contoso Issuing CA
issuer=/CN=Contoso Root CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Certificate bag
Bag Attributes: <No Attributes>
subject=/CN=Contoso Root CA
issuer=/CN=Contoso Root CA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
所以我们的Java代码一定有问题。这是大大简化的 Java 代码:
// keyPassword is set to same value as the keystore password
public void setPrivateKey(PrivateKey key, String alias, String keyPassword, java.security.cert.Certificate[] chain) {
...
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// chain[0] is subject cert and chain[0-N] is ca trust
keyStore.setKeyEntry(alias, key, keyPassword.toCharArray(), chain);
}
编辑1
使用 openssl 3.0.11 将证书复制到 linux。 更新了上面 mytest-personauth.p12 的输出,但 test1.pfx 无法在 Linux 上由 openssl 处理(适用于 macos openssl):
$ openssl pkcs12 -in test1.pfx -info -nokeys -passin pass:'test'
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Error outputting keys and certificates
100000000A000000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:373:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()
找出问题所在。 我正在使用:
KeyStore.getInstance("PKCS12")
它使用内置的 Java 提供程序创建一个 KeyStore。 如果我使用 BC 提供商,一切正常:
KeyStore.getInstance("PKCS12", "BC"
)
简单的解决方案应该更明显。 :(