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

3

17

I'm trying to load certificates directly from the Microsoft store in order to avoid having to export certs from the MS store and then import them into a JKS store.

I managed to get certs created from a typical AD CS web server template using legacy crypto directly from the MS stores using SunMSCAPI.

However, SunMSCAPI does not support the modern CNG ciphers I'm using, specifically RSA-2048 asymmetric encryption, SHA-384 hashing and ECDSA-384 digital signature.

Is it possible to load Next Generation certificates from MS stores using Java? I'm on jdk1.8.0_45. Is there an off-the-shelf JCE provider alternative to SunMSCAPI that can handle CNG? I suspect it would have to use JNI or JNA to access the native Windows CNG API.

I've tried Pheox JCAPI without success. It supports RSA and DSA, but not ECDSA. I have not tried Bouncy Castle, but my understanding is that it does not offer such a capability.

Are there other off-the-shelf JCE provider alternatives to SunMSCAPI that can handle CNG I could try?

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

Update: Some have suggested that installing the 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.

Paratuberculosis answered 27/8, 2015 at 2:44 Comment(10)
What is the final goal? Obviously you plan to use the certificates for some operation. In general, our SecureBlackbox includes classes to use Windows CryptoAPI and CNG (via JNI), but these classes are then used with SecureBlackbox operations and not passable to third-party APIs (on the other hand SecureBlackbox covers all popular security standards, protocols and algorithms, so there's no need to call other libraries).Hodgkin
The main final goal is for SSL. Ideally, I could use the standard javax.net.ssl.* settings to configure a JVM instance to use the Microsoft keystore instead of the JKS default to get certificates.Paratuberculosis
Just in case - SecureBlackbox includes its own SSL engine and uses the certificates which are obtained with other classes of the library (including TElWinCertStorage to get certificates from Windows).Hodgkin
Thanks, but I want to modify the behavior of existing code which uses the standard out-of-the-box Java SSL implementation, not create new code using a third-party SSL package.Paratuberculosis
From docs.oracle.com/javase/8/docs/technotes/guides/security/… all your requirements are met. Are you sure you use the full cipher suite? oracle.com/technetwork/java/javase/downloads/…Prance
Yes, Java 8 supports the ciphers, but SunMSCAPI supports only RSA.Paratuberculosis
As docs.oracle.com/javase/7/docs/technotes/guides/security/… clearly states, you need oracle.com/technetwork/java/javase/downloads/… to use the full cipher suite.Prance
@Prance It would be a bit of a anti climax if the issue was solely the unlimited crypto files. fstarnaud, could you please give it a try and show us the results?Reflation
@MaartenBodewes This is in my pci secure coding top 3 of what java programmers don't know.Prance
Yes, I have the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" for Java 8 installed and obtained here: oracle.com/technetwork/java/javase/downloads/… However, that does not help, since the problem is that the SunMSCAPI supports only the RSA cipher.Paratuberculosis
E
2

As already mentioned, this is not (yet) possible with SunMSCAPI. Actually there is an enhancement request open, where one may vote for the issue to be fixed.

Issue here: https://bugs.openjdk.java.net/browse/JDK-8026953

Emblazonry answered 26/8, 2016 at 15:32 Comment(2)
That issue is now closed.Packing
Yes, fix version is java 13.Emblazonry
P
0

The specification states

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.

Download the JCE Unlimited Strength Jurisdiction Policy Files and place it in your jre security folder.

Prance answered 12/11, 2015 at 20:10 Comment(7)
I cannot really accept such an answer without an indication that this works. I've asked the author of the question but no response yet.Reflation
Your comment is much appreciated. I hope that my answer will help others when stuck with that supid export regulation.Prance
Yes, I have the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" for Java 8 installed. However, that does not help, since the problem is that the SunMSCAPI supports only the RSA cipher.Paratuberculosis
You are correct. SunMSCAPI does not EC. It's supported via SunEC: docs.oracle.com/javase/8/docs/technotes/guides/security/…Prance
Right. And does SunEC support reading keys from the Windows Certificate Store the way SunMSCAPI does?Paratuberculosis
Don't think so. A provider is basically a Map. SunMSCAPI just references other implementations. You could try to add th EC mapping but it's a long shot. Core of the sunMSCAPI is its native integration into windows.Prance
I don't think so either. Perhaps I could eventually try to "add the EC mapping" as you say. But, my understanding is that, to date, I would need to write code, since there doesn't seem to be anything out there that I could use out-of-the-box.Paratuberculosis
O
0

Next generation api is not implemented in sunmscapi c++ code - file security.cpp -, that interacts with windows crypto api. EC is not implemented in java code of sunmscapi also.

You can view the source from openJDK here: http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/556b17038b5c/src/windows/native/sun/security/mscapi/security.cpp

When you call keystore.load(null, null) from your java code, it ends up in c++ code function Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateChains eventually. line 383 CryptAcquireCertificatePrivateKey returns false, since it's not using CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG flag. Even when you fix that line, it eventually breaks down. Since it uses old crypto api functions.

Getting it to work means rewriting all sunmscapi yourself, using new next generation crypto api.

Ohara answered 5/5, 2018 at 6:52 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.