Different types of keystore in Java -- Windows-MY

  Pi Ke        2016-01-09 05:45:59       36,831        6          English  简体中文  繁体中文  ภาษาไทย  Tiếng Việt 

Windows-MY是Windows上一种由Windows操作系统管理的密钥库。它存储用户密钥和证书,这些密钥和证书可用于执行加密操作,例如签名验证、数据加密等。由于它是一种本地密钥库,因此Java没有通用的API来访问它。

为了帮助Java应用程序访问存储在Windows-MY密钥库中的密钥和证书,Java提供了一个单独的API——SunMSCAPI。SunMSCAPI提供程序构建在CAPI之上,并帮助Java平台应用程序使用现有的Java技术安全和加密API访问CAPI加密服务。这意味着Java平台应用程序现在可以使用SunMSCAPI提供程序执行以下操作:

  • 访问存储在CAPI中的私钥和证书
  • 使用CAPI的加密算法实现

下面我们将介绍如何使用Java操作Windows-MY密钥库。

首先,您必须将SunMSCAPI提供程序添加到安全提供程序列表中,以便在创建KeyStore实例时可以找到它。在位于<JAVA_HOME>\lib\security的java.security文件中,添加以下条目:

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

更改上面的数字10以适合您的平台。然后我们可以开始使用Windows-MY。

加载密钥库

要加载密钥库,我们只需要创建一个普通的KeyStore实例并提供密钥库类型Windows-MY

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // 加载密钥库
} catch (Exception ex){
	ex.printStackTrace();
}

这里,密钥库输入为null,密码也为null。由于我们正在操作本机Windows-MY密钥库,因此我们不需要放入密钥库输入流和密码。底层API将自动找到密钥库。

存储私钥和证书链

Windows-MY可用于存储私钥及其关联的证书链。在本教程中,我们将使用CertAndKeyGen生成密钥和证书链。在实际应用程序中,您可能需要使用更复杂的运算。

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // 加载密钥库
	
	// 生成私钥和证书链
	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();
}

存储证书

Windows-MY允许存储没有相应私钥的证书。

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // 加载密钥库
	
	// 生成证书
	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();
}

加载证书链

要加载证书链,我们只需要知道证书链别名。

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

输出如下所示:

[
[
  版本:V3
  主题:CN=JavaSecurity
  签名算法:SHA256withRSA,OID = 1.2.840.113549.1.1.11

  密钥:Sun RSA 公钥,1024 位
  模数:115158915868692318987927322981993098184851087646271166814185733840839228006539416470914033601611753480811872595928340327418479810582683258819388853614402750121845039521565991998963853516232149701424900757572697209325472744440054065298957644144270547136759177167201092105624782153655544642521014196719366849149
  公钥指数:65537
  有效期:[从:2016年1月9日星期六 19:23:49 CST,
               到:2017年1月8日星期日 19:23:49 CST]
  颁发者:CN=JavaSecurity
  序列号:[    5fff31ae]

]
  算法:[SHA256withRSA]
  签名:
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.

]

加载证书

加载证书的过程类似于加载证书链的过程。只需要一个别名。

try{
	KeyStore keyStore = KeyStore.getInstance("Windows-MY");
	keyStore.load(null, null);  // 加载密钥库
	
	Certificate cert = keyStore.getCertificate("mycertificate");

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

输出如下所示:

[
[
  版本:V3
  主题:CN=JavaSecurity1
  签名算法:SHA256withRSA,OID = 1.2.840.113549.1.1.11

  密钥:Sun RSA 公钥,1024 位
  模数:162643520607141934155239883471718040795513791129599245958918873228051267022145247869395776267777056508288312204117354041940752871832185392623715702004286759226626992223635150724845988723904884906298676925643542124198797189444002248973385583978516838174284232569476559210240169899741977273703497762888592391581
  公钥指数:65537
  有效期:[从:2016年1月9日星期六 19:35:04 CST,
               到:2017年1月8日星期日 19:35:04 CST]
  颁发者:CN=JavaSecurity1
  序列号:[    65f0f6d6]

]
  算法:[SHA256withRSA]
  签名:
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.

]

如果您想了解Java中其他类型的密钥库,可以查看Java中不同类型的密钥库——概述

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

Java to Go