如何使用 Java 8 从 Microsoft 密钥库加载下一代证书?

How to load Next Generation certificates from the Microsoft keystore using Java 8?

我正在尝试直接从 Microsoft 商店加载证书,以避免必须从 MS 商店导出证书,然后将它们导入 JKS 商店。

我使用 SunMSCAPI.

直接从 MS 商店使用遗留加密设法从典型的 AD CS Web 服务器模板创建了证书

但是,SunMSCAPI 不支持我使用的现代 CNG 密码,特别是 RSA-2048 非对称加密、SHA-384 哈希和 ECDSA-384 数字签名。

是否可以使用 Java 从 MS 商店加载下一代证书?我在jdk1.8.0_45。是否有现成的 JCE 提供程序替代 SunMSCAPI 可以处理 CNG?我怀疑它必须使用 JNI 或 JNA 来访问本机 Windows CNG API.

我试过 Pheox JCAPI 但没有成功。它支持 RSA 和 DSA,但不支持 ECDSA。我没有尝试过Bouncy Castle,但我的理解是它不提供这样的功能。

是否有其他现成的 JCE 供应商替代 SunMSCAPI 可以处理我可以尝试的 CNG?

更新:JCAPI v2 supports only RSA, ECDH support planned for v3 next year.

更新:有人建议安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for Java 8 could perhaps resolve this, but no, that does not help, since the problem is that SunMSCAPI supports only RSA ciphers, as can be seen looking at the source code.

specification 状态

Due to import regulations in some countries, the Oracle implementation provides a default cryptographic jurisdiction policy file that limits the strength of cryptographic algorithms.

If stronger algorithms are needed (for example, AES with 256-bit keys), the JCE Unlimited Strength Jurisdiction Policy Files must be obtained and installed in the JDK/JRE.

It is the user's responsibility to verify that this action is permissible under local regulations.

下载 JCE Unlimited Strength Jurisdiction Policy Files 并将其放在您的 jre 安全文件夹中。

如前所述,SunMSCAPI(目前)还不可能做到这一点。实际上有一个增强请求打开,人们可以在其中投票赞成要解决的问题。

问题在这里:https://bugs.openjdk.java.net/browse/JDK-8026953

下一代 api 未在 sunmscapi c++ 代码中实现 - 文件 security.cpp - 与 windows 加密 api 交互。 EC 也未在 sunmscapi 的 java 代码中实现。

您可以在此处查看来自 openJDK 的源代码:http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/556b17038b5c/src/windows/native/sun/security/mscapi/security.cpp

当您从 java 代码调用 keystore.load(null, null) 时,它最终会在 c++ 代码函数 Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateChains 中结束。 第 383 行 CryptAcquireCertificatePrivateKey returns false,因为它没有使用 CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG 标志。即使你修复了那条线,它最终也会崩溃。因为它使用旧的加密 api 函数。

让它工作意味着使用新的下一代加密 api 自己重写所有 sunmscapi。