I'm trying to sign an xml file using the XADES4j. I also use the smart card certification (will be loaded from the windows store).
Is there an example that meet my search because i'm new with XML signature and smart cards. I searched a fix for few weeks without success.
There are others example about it but it's not very clear :
I found this demonstration at https://github.com/luisgoncalves/xades4j/wiki/DefiningKeyingData, but I don't know how to set the function PKCS11KeyStoreKeyingDataProvider
to apply the Windows certificate parameters and their pin code:
KeyingDataProvider kp = new PKCS11KeyStoreKeyingDataProvider(
"path/to/native/lib",
"MS SABRI", // CERTIFICATE NAME
new FirstCertificateSelector(),
null,
null,false);,
My code:
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);
I'm not sure what you mean by "Windows store + smart card" as both seem exclusive. Anyway, ff you want to use a smart card, you code is almost OK.
Smart cards usually have a native library that is installed on the host OS. On the first argument of PKCS11KeyStoreKeyingDataProvider
you should pass the path to that library. The second parameter (name
) is just the name to register the instance of the provider. Since the smart card usually handles the PIN to access the key, you usually can supply null
for the keyStorePasswordProvider
and entryPasswordProvider
arguments.
On the library unit tests you can find an example using the Portuguese citizen card.
Hope this helps.