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 中不同類型的密鑰庫 -- 概述。
And about Windows 10.
Exists the "Windows-MY"?