JDK-8133634 : Java gets SunMSCAPI entry as TrustedCertificateEntry instead of PrivateKeyEntry
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 8u45,8u60,9
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2015-06-07
  • Updated: 2022-12-15
  • Resolved: 2019-04-30
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) Client VM (build 25.45-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 7 Enterprise Service Pack 1 x64

A DESCRIPTION OF THE PROBLEM :
With a specific certificate (provided as PKCS#12 for testing) imported on Windows, Java always gets it as TrustedCertificateEntry instead of PrivateKeyEntry.

The certificate has a private key, and you can use it without problems with native Windows applications (C++, C#, etc.).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.- Import this certificate on Windows (password: "adm2013")
         http://1drv.ms/1AUVlVX

2.- Run this simple test method:

    public void testMSCapi() throws Exception {

    	final String ALIAS = "EA=demo.empleado@cgae.redabogacia.org, CN=NOMBRE EMPLEADO EMPLEADO DEMO - NIF 08967425R, OU=Informatica, O=Consejo General de la Abogacía Española / CGAE / 2000, C=ES, ST=Madrid, OID.2.5.4.12=#1308506572736F6E616C, OID.1.3.6.1.4.1.4710.1.3.2=#1309513238363330303649, OID.2.5.4.5=#1309303839363734323552, OID.2.5.4.42=#130444454D4F, OID.2.5.4.4=#1308454D504C4541444F, OID.1.3.6.1.4.1.16533.30.1=#1308454D504C4541444F"; //$NON-NLS-1$

    	final KeyStore ks = KeyStore.getInstance("Windows-MY"); //$NON-NLS-1$
    	ks.load(null, null);

    	final PrivateKeyEntry pke = (PrivateKeyEntry) ks.getEntry(ALIAS, null);

    }

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
You should be able to obtain the PrivateKeyEntry and use it.
ACTUAL -
You get a TrustedCertificateEntry instead of a PrivateKeyEntry, so a "java.security.KeyStore$TrustedCertificateEntry cannot be cast to java.security.KeyStore$PrivateKeyEntry" exception is raised on the test method.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.security.KeyStore$TrustedCertificateEntry cannot be cast to java.security.KeyStore$PrivateKeyEntry

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
    public void testMSCapi() throws Exception {

    	final String ALIAS = "EA=demo.empleado@cgae.redabogacia.org, CN=NOMBRE EMPLEADO EMPLEADO DEMO - NIF 08967425R, OU=Informatica, O=Consejo General de la Abogacía Española / CGAE / 2000, C=ES, ST=Madrid, OID.2.5.4.12=#1308506572736F6E616C, OID.1.3.6.1.4.1.4710.1.3.2=#1309513238363330303649, OID.2.5.4.5=#1309303839363734323552, OID.2.5.4.42=#130444454D4F, OID.2.5.4.4=#1308454D504C4541444F, OID.1.3.6.1.4.1.16533.30.1=#1308454D504C4541444F"; //$NON-NLS-1$

    	final KeyStore ks = KeyStore.getInstance("Windows-MY"); //$NON-NLS-1$
    	ks.load(null, null);

    	final PrivateKeyEntry pke = (PrivateKeyEntry) ks.getEntry(ALIAS, null);

    }
---------- END SOURCE ----------


Comments
Looks like certmgr.exe (I assume this is used to import the p12 file) imports the key/cert into CNG format. Workaround: rename the alias in the p12 file to a simple one first and it can be imported as CAPI format. Note: CNG in JDK 12 only supports EC keys now.
15-02-2019

Assigning to an expert... :) Looks potentially like a key store issue.
15-06-2016