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.
And about Windows 10.
Exists the "Windows-MY"?