2017-10-17 77 views
0

我想使用XADES4j簽署xml文件。我也使用智能卡認證(將從Windows Store中加載)。如何使用XADES4j,證書存儲窗口和智能卡+ PIN碼簽名xml

是否有一個滿足我的搜索的例子,因爲我是新的XML簽名和智能卡。我搜索了幾個星期沒有成功的修復程序。

還有其他的例子吧,但它不是很清楚:

Example1 Example2

,我發現這個示範在https://github.com/luisgoncalves/xades4j/wiki/DefiningKeyingData,但我不知道如何設置功能PKCS11KeyStoreKeyingDataProvider應用的Windows證書的參數和他們的PIN碼:

KeyingDataProvider kp = new PKCS11KeyStoreKeyingDataProvider(
       "path/to/native/lib", 
       "MS SABRI", // CERTIFICATE NAME 
       new FirstCertificateSelector(), 
       null, 
       null,false);, 

我的代碼:

  try { 

    // >>> TEST N°1 
    // KeyingDataProvider kp = new DirectKeyingDataProvider((X509Certificate) certExemple, PrivateKEY); 

     // >>> TEST N°2 
     KeyingDataProvider kp = new PKCS11KeyStoreKeyingDataProvider(
       "path/to/native/lib", 
       "name", // CERTIFICATE NAME 
       new FirstCertificateSelector(), 
       new DirectPasswordProvider("123456"), // PIN CODE 
       new DirectPasswordProvider("123456"), // PIN CODE 
       false); 



     // XADES 
     XadesSigningProfile p = new XadesBesSigningProfile(kp); 
     XadesSigner signer = p.newSigner(); 

     javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); 
     factory.setNamespaceAware(true); 
     javax.xml.parsers.DocumentBuilder builder = null; 
     builder = factory.newDocumentBuilder(); 


     // XML FILE TO BE SIGNED 
     Document doc1 = builder.parse(new File("FileNotSigned.xml")); 

     // NODE 
     Node parentElement   = doc1.getDocumentElement(); 
     Node nodeToSign    = doc1.getDocumentElement().getFirstChild(); 
     Node nodeToAttachSignature = doc1.getDocumentElement(); 


     IndividualDataObjsTimeStampProperty dataObjsTimeStamp = new IndividualDataObjsTimeStampProperty(); 
     AllDataObjsCommitmentTypeProperty globalCommitment = AllDataObjsCommitmentTypeProperty.proofOfApproval(); 
     CommitmentTypeProperty commitment      = CommitmentTypeProperty.proofOfCreation(); 

     // XPATH STRING 
     String xpathHeader ="/InvoiceHeader"; 
     String xpathBody  ="/InvoiceBody"; 

     // OBJECT 
     DataObjectDesc obj1 = new DataObjectReference(""); 
     obj1.withTransform(XPath2Filter.intersect(xpathHeader).intersect(xpathBody)); 
     SignedDataObjects dataObjs = new SignedDataObjects(obj1); 

     // SIGN 
     signer.sign(dataObjs, nodeToAttachSignature); 

     // TRANSFORMER 
     Transformer transformer = TransformerFactory.newInstance().newTransformer(); 

     // XML SIGNED 
     Result output = new StreamResult(new File("FileSigned.xml")); 
     Source input = new DOMSource(doc1); 
     transformer.transform(input, output); 

回答

0

我不確定「Windows商店+智能卡」是什麼意思,因爲兩者似乎都是排他性的。無論如何,如果你想使用智能卡,你的代碼幾乎可以。

智能卡通常具有安裝在主機操作系統上的本機庫。在PKCS11KeyStoreKeyingDataProvider的第一個參數上,您應該將路徑傳遞給該庫。第二個參數(name)只是註冊提供程序實例的名稱。由於智能卡通常處理PIN以訪問密鑰,因此通常可以爲keyStorePasswordProviderentryPasswordProvider參數提供null

在庫單元測試中,您可以找到一個example using the Portuguese citizen card

希望這會有所幫助。

+0

謝謝路易斯的幫助。 我設法成功完成了簽名。但是,當從證書提供程序中檢查xml文件時,他向我發送了這個答案:「securityController中的錯誤:java.lang.String不能轉換爲java.security.cert.X509Certificate」。你能告訴我這個錯誤的原因嗎?我們如何解決它? 再次感謝你的路易斯。 –

+0

異常似乎很明顯..形成堆棧跟蹤,你應該能夠找到導致該問題的代碼行。似乎沒有與xades4j的問題,但讓我知道如果是。 – lgoncalves

+0

是的,它似乎與xades4j沒有問題。我刪除了塊,問題就解決了。我還有其他簽名驗證問題(證書提供者方面),我仍然檢查它們。例如:我必須在簽名塊中保留一個引用(我創建的引用包含XPATH2),因此必須刪除創建的代碼收集到塊的自動引用SignedProperties:通常不會產生問題是不是? 。如果我很快遇到阻塞錯誤,我正在等待您的幫助!再次感謝路易斯。 –