Different types of keystore in Java -- Windows-MY

  Pi Ke        2016-01-09 05:45:59       36,490        6    

Windows-MY is a type of keystore on Windows which is managed by the Windows operating system. It stores the user keys and certificates which can be used to perform cryptographic operations such as signature verification, data encryption etc. Since it's a kind of native keystore, Java doesn't have a general API to access it.

To help Java applications access the keys and certificates stored in Windows-MY keystore, Java provides a separate API -- SunMSCAPI. The SunMSCAPI provider is layered on top of CAPI and helps Java platform applications access CAPI cryptographic services using existing Java technology security and cryptography APIs. This means that Java platform applications can now use the SunMSCAPI provider to do the following:

  • Access private keys and certificates stored in CAPI
  • Use CAPI's cryptographic algorithm implementations

Below we will introduce how to operate Windows-MY keystore using Java.

To start, you have to add the SunMSCAPI provider into the security providers list so that it can be found when creating KeyStore instance. In java.security file located at <JAVA_HOME>\lib\security, add below entry : 

security.provider.10=sun.security.mscapi.SunMSCAPI

Change the number 10 above to suit your platform.  Then we can start to use Windows-MY.

Load keystore

To load the keystore, we just need to create a normal KeyStore instance and provide the keystore type Windows-MY.

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // Load keystore
} catch (Exception ex){
	ex.printStackTrace();
}

Here, the keystore input is null and the password is null as well. Since we are operating on the native Windows-MY keystore, we no ned to put the keystore input stream and password. The underlying API will locate the keystore automatically.

Store private key and certificate chain

Windows-MY can be used to store private keys and their associated certificate chains. In this tutorial, we will use CertAndKeyGen to generate the keys and certificate chain. In real applications, you may need to use more sophisticated operations.

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // Load keystore
	
	// Generate the private key and certificate chain
	CertAndKeyGen certAndKeyGen = new CertAndKeyGen("RSA", "SHA256withRSA");
	certAndKeyGen.generate(1024);
	
	Key key = certAndKeyGen.getPrivateKey();
	X509Certificate cert = certAndKeyGen.getSelfCertificate(new X500Name("CN=JavaSecurity"), 365*24*60*60);
	X509Certificate[] chain = new X509Certificate[]{cert};
	
	keyStore.setKeyEntry("mykey", key, null, chain);
	
	keyStore.store(null, null);
} catch (Exception ex){
	ex.printStackTrace();
}

Store certificate

Windows-MY is allowed to store certificate without its corresponding private key.

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // Load keystore
	
	// Generate the certificate
	CertAndKeyGen certAndKeyGen = new CertAndKeyGen("RSA", "SHA256withRSA");
	certAndKeyGen.generate(1024);
	
	X509Certificate cert = certAndKeyGen.getSelfCertificate(new X500Name("CN=JavaSecurity1"), 365*24*60*60);

	keyStore.setCertificateEntry("mycertificate", cert);
	
	keyStore.store(null, null);
} catch (Exception ex){
	ex.printStackTrace();
}

Load certificate chain

To load the certificate chain, we just need to know about the certificate chain alias.

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // Load keystore
	
	Certificate[] chain = keyStore.getCertificateChain("mykey");
	
	for(Certificate cert : chain){
		System.out.println(cert);
	}
} catch (Exception ex){
	ex.printStackTrace();
}

The output looks like:

[
[
  Version: V3
  Subject: CN=JavaSecurity
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 1024 bits
  modulus: 115158915868692318987927322981993098184851087646271166814185733840839228006539416470914033601611753480811872595928340327418479810582683258819388853614402750121845039521565991998963853516232149701424900757572697209325472744440054065298957644144270547136759177167201092105624782153655544642521014196719366849149
  public exponent: 65537
  Validity: [From: Sat Jan 09 19:23:49 CST 2016,
               To: Sun Jan 08 19:23:49 CST 2017]
  Issuer: CN=JavaSecurity
  SerialNumber: [    5fff31ae]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 9C 1D 36 4E 31 CA CD A5   06 13 A5 7E A8 7B 0C 7F  ..6N1...........
0010: 71 D9 0A 2B 19 82 28 D3   E0 9D A1 FD 5E 5E 8C CB  q..+..(.....^^..
0020: 77 77 AF 4B E1 29 27 D5   CE 77 8E 68 2C DA A4 30  ww.K.)'..w.h,..0
0030: CA 5F 66 5E B7 C8 4E 81   15 CB A9 56 5D 34 76 28  ._f^..N....V]4v(
0040: 42 59 65 C1 E2 7E D6 6D   1A A3 66 83 D2 1E C9 10  BYe....m..f.....
0050: 9F 05 75 E3 83 7D D2 70   FA 28 49 42 57 38 18 4B  ..u....p.(IBW8.K
0060: E7 C9 17 8D 13 7C 81 F5   2C 5D 04 2E 15 04 77 60  ........,]....w`
0070: 85 7B 45 E7 A6 A7 C9 62   63 D4 26 50 83 38 74 AD  ..E....bc.&P.8t.

]

Load certificate

The process of loading certificate is similar to that of loading certificate chain. Only an alias is needed.

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // Load keystore
	
	Certificate cert = keyStore.getCertificate("mycertificate");

	System.out.println(cert);
} catch (Exception ex){
	ex.printStackTrace();
}

The output looks like:

[
[
  Version: V3
  Subject: CN=JavaSecurity1
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 1024 bits
  modulus: 162643520607141934155239883471718040795513791129599245958918873228051267022145247869395776267777056508288312204117354041940752871832185392623715702004286759226626992223635150724845988723904884906298676925643542124198797189444002248973385583978516838174284232569476559210240169899741977273703497762888592391581
  public exponent: 65537
  Validity: [From: Sat Jan 09 19:35:04 CST 2016,
               To: Sun Jan 08 19:35:04 CST 2017]
  Issuer: CN=JavaSecurity1
  SerialNumber: [    65f0f6d6]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: BE 9F 8C 5D 02 A7 49 35   AE 66 75 2F C5 F2 2B D2  ...]..I5.fu/..+.
0010: BF 8D 37 F8 A3 DE 33 9C   F8 64 96 67 E8 00 F6 B5  ..7...3..d.g....
0020: 13 C6 CF 95 63 B2 14 BE   4D D1 AD 26 FF BF 5C BC  ....c...M..&..\.
0030: F0 4F DD E7 A4 BC 9E 88   E5 23 CB 4C 0D B4 C6 8F  .O.......#.L....
0040: 4D B5 69 F5 EF 7F 90 66   29 59 9D 87 37 B9 A3 51  M.i....f)Y..7..Q
0050: 54 1C BF AF 54 6C 4B 72   47 3A 2A 3C B0 E9 08 C1  T...TlKrG:*<....
0060: E1 A8 98 1A 7F CC F5 D1   5A 12 3F 70 A3 5A E6 F3  ........Z.?p.Z..
0070: 3D 23 FD 04 45 3F EA 26   3B D8 D2 72 B6 A4 47 AA  =#..E?.&;..r..G.

]

If you want to know about other types of keystore in Java, you can take a look at Different types of keystore in Java -- Overview.

JAVA  KEYSTORE  WINDOWS-MY  SUNMSCAPI 

       

  RELATED


  6 COMMENTS


Anonymous [Reply]@ 2016-03-29 10:27:17

And about Windows 10.

Exists the "Windows-MY"?

Ke Pi [Reply]@ 2016-03-29 21:52:25

Sorry I don't have a Windows 10 yet. So didn't test it on Windows 10. You can give a try if you have Windows 10 :)

Anonymous [Reply]@ 2016-06-16 21:09:56

If I have a token device fully configured on my pc, and I can see the certificates stored on a token. (I can see them via Internet Explorer options)

Is it possible to retrieve the certificates from the SmartCard with the SunMSCAPI provider for digital signing??

 

Thanks. 

Chris

 

Ke Pi [Reply]@ 2016-06-17 07:50:39

Hi, Chris,

SunMSCAPI is to manage Window-MY keystore. Your Smart Card should be a HSM which needs to be handled using PKCS11 provider. PKCS11 API is used to access hardware keystores.

As for the certificate extraction, t depends on whether your smart card allows the certificate to be extracted or not. Some smart cards are designed so that nothing can be extracted from it. But some do allow extraction. So check with your card vendor specification on this.

 

Anonymous [Reply]@ 2016-06-19 21:54:38

I see, that means that i can only perform digital signing via PKCS11 API but not indirectly via SunMSCAPI. 

Thank you so much.

Chris

Anonymous [Reply]@ 2018-02-08 08:02:24

Is there any way to find out the list of all Personal certificate installed on a windows 10 machine using any JAVA?

Looking for using it to automate a test case where using java or/and selenium script need to find out a specific personal certificate that installed on a Windows 10 device.



  RANDOM FUN

Vue but not Vue.js