Assinatura de nota Fiscal Eletronica

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]

gsfteodoro,

Essel link pode te ajudar: http://www.javac.com.br/jc/posts/list/106-nfe-assinatura-dos-xmls-de-envio-de-lote-cancelamento-e-inutilizacao-certificado-a1.page.

Fala luiz_renato.

Então, como disse, consigo assinar o XML.
O Problema é que tenho que assinar um conteúdo de dentro do XML e o XML inteiro, ou seja, haverão duas assinaturas.

Mas obrigado mesmo assim.

Então, na sua rotina que assina o xml, você deve estar passando uma String(todo conteudo do xml) como parametro para a função, certo ?
Você precisa pegar somente a parte do xml que diz respeito a RPS, e passar para esta mesma função, repetindo a operação para cada RPS do seu lote. Ao final, você junta tudo e assina novamente.

Entendi, guimoz.

Pensei que poderia haver outra forma… Vou Fazer assim então. Obrigado pela força.