2017-10-17 34 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:通常不会产生问题是不是? 。如果我很快遇到阻塞错误,我正在等待您的帮助!再次感谢路易斯。 –