Different types of keystore in Java -- Windows-MY

  Pi Ke        2016-01-09 05:45:59       36,833        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

localhost is so famous