Assinar digitalmente o arquivo XML
O código abaixo utiliza a classe TokenReader para obter o certificado digital:
JPasswordField jpf = new JPasswordField();
JOptionPane.showConfirmDialog(
null, jpf, "Senha:", JOptionPane.OK_CANCEL_OPTION);
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
Reference ref = fac.newReference(
"", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(
fac.newTransform(
Transform.ENVELOPED, (TransformParameterSpec) null)),
null, null);
SignedInfo si = fac.newSignedInfo(
fac.newCanonicalizationMethod(
CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
TokenReader token = new TokenReader();
token.openKeyStore(jpf.getPassword());
X509Certificate cert = token.getCertificate();
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc =
dbf.newDocumentBuilder().parse(
new FileInputStream("arquivo_nao_assinado.xml"));
DOMSignContext dsc = new DOMSignContext(
token.getPrivateKey(), doc.getDocumentElement());
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);
OutputStream os = new FileOutputStream("arquivo_entrada.xml");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
Esse código abre o arquivo "arquivo_nao_assinado.xml" e a partir dele cria o XML "arquivo_entrada.xml", assinado pelo certificado digital do token USB inserido, pedindo a senha (PIN) do token em uma pequena janela.