Eu consegui assinar a NFSe com o código:
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Assinador {
private PrivateKey privateKey;
private KeyInfo keyInfo;
private Document document;
private XMLSignatureFactory signatureFactory;
private ArrayList<Transform> transformList;
private NodeList elements;
private org.w3c.dom.Element el;
private Reference ref;
private SignedInfo si;
private XMLSignature signature;
private DOMSignContext dsc;
private static final String RPS = "tipos:Rps";
private static final String EnviarLoteRpsEnvio = "LoteRps";
public static String lerXML(String fileXML) throws IOException {
String linha = "";
StringBuilder xml = new StringBuilder();
BufferedReader in = new BufferedReader(new InputStreamReader(
new FileInputStream(fileXML), "ISO-8859-1"));
while ((linha = in.readLine()) != null) {
xml.append(linha);
}
in.close();
return xml.toString();
}
private String outputXML(Document doc) throws TransformerException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
String xml = os.toString();
if ((xml != null) && (!"".equals(xml))) {
xml = xml.replaceAll("\\r\\n", "");
xml = xml.replaceAll(" standalone=\"no\"", "");
}
return xml;
}
private void loadCertificates(String certificado, String senha,
XMLSignatureFactory signatureFactory) throws Exception {
InputStream entrada = new FileInputStream(certificado);
KeyStore ks = KeyStore.getInstance("PKCS12");
try {
ks.load(entrada, senha.toCharArray());
} catch (IOException e) {
throw new Exception(
"Senha do Certificado Digital incorreta ou Certificado inválido.");
}
KeyStore.PrivateKeyEntry pkEntry = null;
Enumeration<String> aliasesEnum = ks.aliases();
while (aliasesEnum.hasMoreElements()) {
String alias = (String) aliasesEnum.nextElement();
if (ks.isKeyEntry(alias)) {
pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias,
new KeyStore.PasswordProtection(senha.toCharArray()));
privateKey = pkEntry.getPrivateKey();
break;
}
}
X509Certificate cert = (X509Certificate) pkEntry.getCertificate();
// info("SubjectDN: " + cert.getSubjectDN().toString());
KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
List<X509Certificate> x509Content = new ArrayList<X509Certificate>();
x509Content.add(cert);
X509Data x509Data = keyInfoFactory.newX509Data(x509Content);
keyInfo = keyInfoFactory
.newKeyInfo(Collections.singletonList(x509Data));
}
private Document documentFactory(String xml) throws SAXException,
IOException, ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document document = factory.newDocumentBuilder().parse(
new ByteArrayInputStream(xml.getBytes()));
return document;
}
private ArrayList<Transform> signatureFactory(
XMLSignatureFactory signatureFactory)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
ArrayList<Transform> transformList = new ArrayList<Transform>();
TransformParameterSpec tps = null;
Transform envelopedTransform = signatureFactory.newTransform(
Transform.ENVELOPED, tps);
Transform c14NTransform = signatureFactory.newTransform(
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315", tps);
transformList.add(envelopedTransform);
transformList.add(c14NTransform);
return transformList;
}
public void assinaLoteRpsNFSe(String tipo, XMLSignatureFactory fac,
ArrayList<Transform> transformList, PrivateKey privateKey,
KeyInfo ki, Document document, int indexNFe)
throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException, MarshalException,
XMLSignatureException, javax.xml.crypto.MarshalException {
if (tipo.equals(Assinador.EnviarLoteRpsEnvio)) {
this.elements = this.document.getDocumentElement()
.getElementsByTagName("LoteRps");
}
if (tipo.equals(Assinador.RPS)) {
this.elements = this.document.getElementsByTagName("tipos:InfRps");
}
this.el = (org.w3c.dom.Element) this.elements.item(indexNFe);
String id = el.getAttribute("Id");
el.setIdAttribute("Id", true);
this.ref = fac.newReference("#" + id,
fac.newDigestMethod(DigestMethod.SHA1, null), transformList,
null, null);
this.si = fac
.newSignedInfo(fac.newCanonicalizationMethod(
CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null), fac
.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
this.signature = fac.newXMLSignature(si, ki);
this.dsc = new DOMSignContext(privateKey,
/*
* document.getDocumentElement().getElementsByTagName(tipo).item(indexNFe
* )
*/this.document.getFirstChild());
this.signature.sign(this.dsc);
}
public void assinaInfRpsNFSe(String tipo, XMLSignatureFactory fac,
ArrayList<Transform> transformList, PrivateKey privateKey,
KeyInfo ki, Document document, int indexNFe)
throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException, MarshalException,
XMLSignatureException, javax.xml.crypto.MarshalException {
if (tipo.equals(Assinador.EnviarLoteRpsEnvio)) {
this.elements = this.document.getDocumentElement()
.getElementsByTagName("LoteRps");
}
if (tipo.equals(Assinador.RPS)) {
this.elements = this.document.getElementsByTagName("tipos:InfRps");
}
this.el = (org.w3c.dom.Element) this.elements.item(indexNFe);
String id = el.getAttribute("Id");
el.setIdAttribute("Id", true);
this.ref = fac.newReference("#" + id,
fac.newDigestMethod(DigestMethod.SHA1, null), transformList,
null, null);
this.si = fac
.newSignedInfo(fac.newCanonicalizationMethod(
CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null), fac
.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
this.signature = fac.newXMLSignature(si, ki);
this.dsc = new DOMSignContext(privateKey, document.getDocumentElement()
.getElementsByTagName(tipo).item(indexNFe));
this.signature.sign(this.dsc);
}
public String assinaXML(String acao, String xml, String certificado,
String senha) throws Exception {
if (acao.equals("NFSe")) {
return assinaNFSe(xml, certificado, senha, 0);
}
return null;
}
public String assinaNFSe(String xml, String certificado, String senha,
int indexNFe) throws Exception {
this.document = documentFactory(xml);
this.signatureFactory = XMLSignatureFactory.getInstance("DOM");
this.transformList = signatureFactory(this.signatureFactory);
loadCertificates(certificado, senha, this.signatureFactory);
assinaLoteRpsNFSe(Assinador.EnviarLoteRpsEnvio, this.signatureFactory,
this.transformList, this.privateKey, this.keyInfo,
this.document, 0);
for (int i = 0; i < this.document.getDocumentElement()
.getElementsByTagName(Assinador.RPS).getLength(); i++) {
assinaInfRpsNFSe(Assinador.RPS, this.signatureFactory,
this.transformList, this.privateKey, this.keyInfo,
this.document, i);
}
return outputXML(this.document);
}
}
Tente adaptar para seu caso já que o original assinava NFe.
Qualquer dúvida posta ai que nós ajudamos.