Olá a todos.
Eu estou desenvolvendo um tipo de envio de Nota Fiscal Eletrônica, consegui criar o XML, assinar o conteúdo total do XML porém não consigo fazer uma assinatura que fica no meio do corpo XML.
Estou o dia inteiro buscando somente este ítem.
Meu xml está assim:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header/>
<soapenv:Body>
<e:EnviarLoteRpsEnvio xmlns:e="http://www.betha.com.br/e-nota-contribuinte-ws">
<LoteRps Id="Lote5724">
<NumeroLote>5724</NumeroLote>
<Cnpj>02762121000449</Cnpj>
<InscricaoMunicipal>265958</InscricaoMunicipal>
<QuantidadeRps>1</QuantidadeRps>
<ListaRps>
<Rps>
<InfRps Id="Rps5724">
......
</InfRps>
</Rps>
</ListaRps>
</LoteRps>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#Rps5724">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>Q0Y1jQ+6GhKFBiFxh+PJcnn9hCg=</DigestValue>
</Reference>
<Reference URI="#Lote5724">
<Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>c+F1B/1qsr8MIdg7iOHFB39eMpE=</DigestValue></Reference>
</SignedInfo><SignatureValue>nhaaZRSRSxY49G6/bPq8B15avDY7F5XC2xJ1kOtagRoGRX17cz+jSQF39BubIE1gZv+6RoiFSzr9
NZ4/1nKnA2OXQJ1P5s9Jdt7skthxLdNGqE4r6vNeH/8ImeTzBo9mcVxozFNWo4fMHFE+coCF2MO1
rXECRAgNjXr1d/FIfk4=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIGMTCCBRmgAwIBAgIIGN1dKE9CR+UwDQYJKoZIhvcNAQEFBQAwTDELMAkGA1UEBhMCQlIxEzAR
BgNVBAoTCklDUC1CcmFzaWwxKDAmBgNVBAMTH1NFUkFTQSBDZXJ0aWZpY2Fkb3JhIERpZ2l0YWwg
djEwHhcNMTEwNzE5MTMwNjUyWhcNMTIwNzE4MTMwNjUyWjCB6zELMAkGA1UEBhMCQlIxEzARBgNV
BAoTCklDUC1CcmFzaWwxFDASBgNVBAsTCyhFTSBCUkFOQ08pMRgwFgYDVQQLEw8wMDAwMDEwMDE5
ODIyNTYxFDASBgNVBAsTCyhFTSBCUkFOQ08pMRQwEgYDVQQLEwsoRU0gQlJBTkNPKTEUMBIGA1UE
CxMLKEVNIEJSQU5DTykxFDASBgNVBAsTCyhFTSBCUkFOQ08pMRQwEgYDVQQLEwsoRU0gQlJBTkNP
KTEpMCcGA1UEAxMgU0FOVE9TIEJSQVNJTCBQQVJUSUNJUEFDT0VTIFMuQS4wgZ8wDQYJKoZIhvcN
AQEBBQADgY0AMIGJAoGBAOQ0nDNNXDLQZjYVWKPCO2UK5dgrogji1UB6TIOztlw11TJovP/qmlhy
NqhJCbl14mrfoMeH+1LCzgEct/68RrG57VRmliDApSnXwhrrLMYMmTLQvvYrrTMawe0kiUYeWQXt
DxKRQn4EfVYtiOcBYL4+F47Wx36J9UgZjzuSk8dxAgMBAAGjggL5MIIC9TAOBgNVHQ8BAf8EBAMC
BeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB8GA1UdIwQYMBaAFLdgqFv5sqauAO10
69VKyZZoZvVcMIG8BgNVHREEgbQwgbGBF1JBRkBTQU5UT1NCUkFTSUwuQ09NLkJSoD0GBWBMAQME
oDQTMjEzMDgxOTY3MDU3NjQzMDk4NjcwMDAwMDAwMDAwMDAwMDAwMDAxMzk5ODU5NVNTUFNQoCMG
BWBMAQMCoBoTGFJJQ0FSRE8gQUJCUlVaWklOSSBGSUxIT6AZBgVgTAEDA6AQEw4wMjc2MjEyMTAw
MDEwNKAXBgVgTAEDB6AOEwwwMDAwMDAwMDAwMDAwVwYDVR0gBFAwTjBMBgZgTAECAQYwQjBABggr
BgEFBQcCARY0aHR0cDovL3d3dy5jZXJ0aWZpY2Fkb2RpZ2l0YWwuY29tLmJyL3JlcG9zaXRvcmlv
L2RwYzCB8AYDVR0fBIHoMIHlMEmgR6BFhkNodHRwOi8vd3d3LmNlcnRpZmljYWRvZGlnaXRhbC5j
b20uYnIvcmVwb3NpdG9yaW8vbGNyL3NlcmFzYWNkdjEuY3JsMEOgQaA/hj1odHRwOi8vbGNyLmNl
cnRpZmljYWRvcy5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL3NlcmFzYWNkdjEuY3JsMFOgUaBPhk1o
dHRwOi8vcmVwb3NpdG9yaW8uaWNwYnJhc2lsLmdvdi5ici9sY3IvU2VyYXNhL3JlcG9zaXRvcmlv
L2xjci9zZXJhc2FjZHYxLmNybDCBlwYIKwYBBQUHAQEEgYowgYcwRwYIKwYBBQUHMAKGO2h0dHA6
Ly93d3cuY2VydGlmaWNhZG9kaWdpdGFsLmNvbS5ici9jYWRlaWFzL3NlcmFzYWNkdjEucDdiMDwG
CCsGAQUFBzABhjBodHRwOi8vb2NzcC5jZXJ0aWZpY2Fkb2RpZ2l0YWwuY29tLmJyL3NlcmFzYWNk
djEwDQYJKoZIhvcNAQEFBQADggEBAIvcpJ6piK2j8pKl/4wF7zY4ISRYYJhX6x3Jd3OtKyRLkMa9
kaNczv3kvitVywZwcSTYFx+rVDCGhIM80ZAo29XHUbdy/wscLEioQ/rz644SQ4NHuDo6KiG4Vjy0
BR2iST5UsRlQ9yS2YXPRFi+R3UviHmfvoXBHy3H4joNAJJ4U0yS4PFRHB36V32Pd3iQf30hdzdzM
V9CG6yyK6N5qNa9QkZBOpHRmHuiu8AMpLnoH+DF+v7D5pXs+f0l/DVspuSiCREYVTFO1KH97AKVw
QOlRucdhkF2WWTaTU2KiAFOgIx8/LoZDeqZvv6Pg9Sbn5i59vHwPFA3dknZB0ftUz9s=</X509Certificate></X509Data></KeyInfo></Signature></e:EnviarLoteRpsEnvio>
Porém, como podem observar, existe a URI Rps. De acordo com o exemplo que me foi passado, tenho que assinar o final do arquivo e cada Rps.
Como fazer isso?
Meu código:
[code]String result = “”;
KeyStore ks;
KeyInfo ki=null;
KeyStore.PrivateKeyEntry keyEntry = null;
try {
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(arquivo), senhaArquivo.toCharArray());
keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry (chave, new KeyStore.PasswordProtection(senhaChave.toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
ki = kif.newKeyInfo(Collections.singletonList(xd));
}
catch (KeyStoreException ex) {
Logger.getLogger(AssinaturaRsa.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(AssinaturaRsa.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(AssinaturaRsa.class.getName()).log(Level.SEVERE, null, ex);
} catch (CertificateException ex) {
Logger.getLogger(AssinaturaRsa.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnrecoverableEntryException ex) {
Logger.getLogger(AssinaturaRsa.class.getName()).log(Level.SEVERE, null, ex);
}
// Instantiate the document to be signed.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(corpo.getBytes("UTF-8")));
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature's parent element.
DOMSignContext dsc = new DOMSignContext
(keyEntry.getPrivateKey(), doc.getDocumentElement());
// Create the XMLSignature, but don't sign it yet.
XMLSignature signature = fac.newXMLSignature(si, ki);
// Marshal, generate, and sign the enveloped signature.
signature.sign(dsc);
OutputStream f2 = new ByteArrayOutputStream();
//OutputStream f2 = new ByteOutputStream();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.transform(new DOMSource(doc), new StreamResult(f2));
if (cabecalho) result = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soapenv:Header/> \n";
//xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance
if (cabecalho)result += "<soapenv:Body>\n";
result += f2.toString();
if (cabecalho)result += "\n</soapenv:Body>\n";
if (cabecalho)result += "</soapenv:Envelope>";
return result;[/code]
Trecho que cria as URIs:
[code] // Criação do DOM XMLSignatureFactory será usado
// na criação do envelope de assinatura.
fac = XMLSignatureFactory.getInstance(“DOM”);
// Criando a referencia para o envelope da assinatura
List<Reference> ref = new ArrayList<Reference>();
try {
ArrayList transformList = new ArrayList();
TransformParameterSpec tps = null;
Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED, tps);
Transform c14NTransform = fac.newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315",tps);
transformList.add(envelopedTransform);
transformList.add(c14NTransform);
for (String n : nos){
ref.add(fac.newReference
((n.equals("")?"":"#") + n, fac.newDigestMethod(DigestMethod.SHA1, null),
transformList,null,null));
}
// Criação do SignedInfo.
si = fac.newSignedInfo
(fac.newCanonicalizationMethod
(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
ref);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(AssinaturaRsa.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(AssinaturaRsa.class.getName()).log(Level.SEVERE, null, ex);
}[/code]