2011-03-29 23 views
8

我需要在Windows上構建證書鏈,從X.509智能卡證書通過一個或多箇中間CA到根CA.當CA證書位於JKS密鑰庫中時,這很容易,但我也需要使用Windows密鑰庫。從Windows密鑰庫對中間CA進行Java訪問?

我可以從「Windows-ROOT」獲得根CA證書,但我無法進入「中級證書頒發機構」密鑰庫。

有沒有人這樣做?

謝謝!

回答

8

SunMSCAPI加密提供程序只支持兩個密鑰存儲:Windows-MY(個人證書存儲)和Windows-ROOT(可信機構證書存儲),因此我不認爲有可能直接訪問其他Windows證書存儲。但它可能不是必需的,因爲Windows-MY密鑰庫似乎能夠使用來自其他存儲的證書構建證書鏈。

這裏是一個代碼段我使用來測試它:

KeyStore ks = KeyStore.getInstance("Windows-MY"); 
ks.load(null, null) ; 
Enumeration en = ks.aliases() ; 
while (en.hasMoreElements()) { 
    String aliasKey = (String)en.nextElement() ; 
    Certificate c = ks.getCertificate(aliasKey) ; 
    System.out.println("---> alias : " + aliasKey) ; 
    if (ks.isKeyEntry(aliasKey)) { 
     Certificate[] chain = ks.getCertificateChain(aliasKey); 
     System.out.println("---> chain length: " + chain.length); 
     for (Certificate cert: chain) { 
      System.out.println(cert); 
    } 
} 

如果我添加與所述個人證書存儲的鏈長度爲1。私鑰單個證書中的中間CA添加CA之後證書存儲在我啓動程序的第二時間,現在鏈長爲2

UPDATE(四月2日) 有可能在Windows-MYWindows-ROOT密鑰庫有一些限制以編程方式添加證書:

  • 添加在Windows-ROOT證書時,用戶被提示確認
  • 所有證書中的密鑰庫Windows-MY加入是TrustedCertificateEntry(從視點密鑰庫,而不是在Windows的觀點)。密鑰庫似乎用所有可用的證書構建了最長的鏈。
  • 沒有關聯私鑰的證書在Windows證書存儲瀏覽器中不可見,但可以通過編程方式刪除它們。

添加在密鑰庫中的證書很簡單:

Certificate c = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream("C:/Users/me/Downloads/myca.crt")); 
KeyStore.TrustedCertificateEntry entry = new KeyStore.TrustedCertificateEntry(c); 
ks.setEntry("CA1", entry , null); 
+0

是的,如果用戶的證書在個人商店中沒有問題。我想知道我是否可以通過編程方式添加它? – Mermeister 2011-04-01 16:51:10

+0

是的,這是可能的。我用更多細節更新我的答案。 – Jcs 2011-04-02 07:42:50

+0

這工作!我從智能卡檢索我的用戶證書,以編程方式將其添加到Windows-MY商店,然後使用Windows密鑰存儲庫構建鏈。 – Mermeister 2011-04-07 19:56:57

1

JCS有了答案,但我想說明一些僞這樣:

// load the Windows keystore 
KeyStore winKeystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); 
winKeystore.load(null, null); 

// add the user's smart card cert to the keystore 
winKeystore.setCertificateEntry(myAlias, userCertificate); 

// build the cert chain! this will include intermediate CAs 
Certificate[] chain = winKeystore.getCertificateChain(myAlias); 

的Windows證書鏈不驗證因爲它們已經建好了,但現在你可以通過創建一個CertPath和PKIXParameters並使用它們來驗證鏈。

CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType()); 
certPathValidator.validate(certPath, params);