2011-11-10 26 views
2

我試圖從MS-KeyStore簽署具有不同證書的字符串。 但是,我知道從M​​S-Keystore中的令牌導入密​​鑰。 所以,我的問題是 - 如果我通過密鑰庫並嘗試簽署帶有對pkcs11的引用的證書,我會彈出輸入pkcs11密碼。 如何檢查證書是否來自我的令牌?Java - PKCS11和MSKeyStore

在此先感謝!

這是我的代碼現在:

String alias; 
    byte[] data = "test".getBytes(); 
    char[] pin = "pass".toCharArray(); 

    try { 


     KeyStore ks = KeyStore.getInstance("Windows-MY"); 
     ks.load(null, pin); 
     System.out.println("Provider: "+ks.getProvider()); 
     System.out.println("KS size: " + ks.size()); 

     Enumeration enumeration = ks.aliases(); 

     while (enumeration.hasMoreElements()) { 
      alias = (String) enumeration.nextElement(); 

      PrivateKey privateKey = (PrivateKey) ks.getKey(alias, null); 
      Certificate certificate = ks.getCertificate(alias); 

      Provider provider = ks.getProvider(); 
      Signature signature = Signature.getInstance("SHA1withRSA", provider); 
      try { 
       signature.initSign(privateKey); 
       signature.update(data); 

       byte[] signedSignature = signature.sign(); 
       System.out.println("\tGenerated signature for " + alias); 

       signature.initVerify(certificate); 
       signature.update(data); 
       if (signature.verify(signedSignature)) { 
        System.out.println("\tSignature verifified for " + alias); 
       } else { 
        System.out.println("\tCould not verify signature for " + alias); 
       } 
      } catch (Exception ex) { 
       System.out.println("\tError for " + alias); 
      } 

     } 

    } catch (KeyStoreException e) { 
     e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
    } catch (CertificateException e) { 
     e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
    } catch (IOException e) { 
     e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
    } catch (UnrecoverableKeyException e) { 
     e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
    } 
+0

嗯,我不太明白。如果「出現彈出窗口並要求您輸入密碼」,您的問題是什麼?如果證書來自外部令牌,則這是它將被使用的方式:在檢索HSM的內容時,需要密碼。我可以說你想將外部令牌的證書與「軟」/導入到IE證書區分開來嗎? – FaithReaper

回答

0

恐怕你不能可靠地告訴證書的來源,至少不是在Java級別爲MS CAPI提供商。但這是設計的一部分 - MS CAPI或多或少地打算封裝和隱藏證書/密鑰的來源。

一個安全的方式來告訴您的密鑰/證書來自PKCS#11設備將使用SUN PKCS#11 provider。但是,這有一個缺點,即需要靜態(在可以靜態配置提供程序的java.security文件中)指定原生PKCS#11庫的路徑,或者以用戶輸入的形式動態請求它。

如果在您的情況下使用PKCS#11提供程序太麻煩了,我會建議實施證書選擇對話框,以篩選合適的證書。通過將MSCAPI限制爲PKCS#11來源的證書,安全性沒有直接的好處 - 您的用戶安裝了其他證書/密鑰(通常採用PKCS#12文件的形式)可能是一個很好的理由。您應該只檢查(並且幫助用戶已經過濾了重寫此標準的證書)最終選擇的證書/密鑰符合您的標準:正確的密鑰使用(例如數字簽名),聲音擴展密鑰使用,存在的可接受或已知的策略證書等

在歐盟,我們正在慢慢向「安全簽名創建設備上的合格證書」的概念發展。這意味着在這樣的設備(例如智能卡)上附帶的證書將包含特殊策略,CA不得將這些策略用於任何其他證書,例如軟件證書。因此,這將有效地確保證書來源於安全的硬件設備。您可能會檢查涉及的證書是否支持此功能。這ETSI document列出您將不得不尋找相應的OID。

0

在Java密鑰存儲區中,應該鏈接密鑰和證書的別名。基本上,私鑰輸入是私鑰+證書鏈。所以證書應該始終來自密鑰庫。當然,如果證書來自實際的令牌,那麼當然是直到實現密鑰存儲。檢查它們是否實際來自令牌的唯一方法是使用不同的方法檢索它們(例如直接從令牌讀取證書的字節)。沒有鏈接返回到存儲設備的證書,如果這是你以後。

當然,檢查完整的證書鏈直到根證書是有意義的。如果根證書不經常更改,則可以考慮將證書或散列存儲在隨應用程序提供的資源中的根證書上,或者將其散佈到標準Java密鑰存儲中。