Erro ao tentar assinar o XML com o Certificado Digital

Prezados,

Estou tentando assinar um XML com o Certificado Digital, porem esta ocorrendo o seguinte erro:

java.io.IOException: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1277)
at java.security.KeyStore.load(KeyStore.java:1185)
at br.com.cienci.nfe.signature.DigitalSignature.sign(DigitalSignature.java:78)
at br.com.cienci.nfe.rfc.ConsultaCnpjWs.getIncricaoMunicipal(ConsultaCnpjWs.java:43)
at br.com.cienci.nfe.parser.Teste.main(Teste.java:20)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*…)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*…)
at com.sun.crypto.provider.PKCS12PBECipherCore.b(DashoA13*…)
at com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_40.engineDoFinal(DashoA13*…)
at javax.crypto.Cipher.doFinal(DashoA13*…)
at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1274)
… 4 more

Agradeço muito, se alguem puder ajudar, pois estou tentando resolver este problema ja faz um certo tempo…

Obs. Aparece erro de SSL, porem nao estou utilizando o container para testar a classe…

Grato desde já Elton C.

Vc montou o hash certo ?

Qual a dll que vc esta usando ? Eh a Criptlib ? Ela esta instalada ?

Baixou a segurança do seu browser ? ( se for web a assinatura. )

O cabeçalho do xml nao pode ter erro algum!

Qual a biblioteca de assinatura vc esta usando ?

O codigo esta correto, acabei de testar na maquina do outro programador que esta trabalhando no mesmo projeto e funcionou, so na minha maquina que esta com este problema…

Segue o codigo responsavel pela assinatura :

[code]package br.com.cienci.nfe.signature;

import br.com.cienci.nfe.parser.NfeUtil;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import javax.xml.crypto.;
import javax.xml.crypto.dsig.
;
import javax.xml.crypto.dom.;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.
;
import javax.xml.crypto.dsig.spec.;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.security.
;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;

/**
*

  • @author Ciro S. Santos
    */
    public class DigitalSignature {

    private static final String C14N_TRANSFORM_METHOD = “http://www.w3.org/TR/2001/REC-xml-c14n-20010315”;
    private static final String PROVIDER_CLASS_NAME = “org.jcp.xml.dsig.internal.dom.XMLDSigRI”;
    private static final String PROVIDER_NAME = “jsr105Provider”;

    public String sign(String xml, String certificado, String senha) {

     String result = "";
    
     try {
         String providerName = System.getProperty(PROVIDER_NAME, PROVIDER_CLASS_NAME);
    
         XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
                 (Provider) Class.forName(providerName).newInstance());
    
         ArrayList<Transform> transformList = new ArrayList<Transform>();
         TransformParameterSpec tps = null;
         Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED, tps);
         Transform c14NTransform = fac.newTransform(C14N_TRANSFORM_METHOD, tps);
         transformList.add(envelopedTransform);
         transformList.add(c14NTransform);
    
         Reference ref = fac.newReference("",
                 fac.newDigestMethod(DigestMethod.SHA1, null),
                 transformList,
                 null,
                 null);
    
         SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
                 (C14NMethodParameterSpec) null),
                 fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                 Collections.singletonList(ref));
    
        //File file = new File("src\\securityResources");
         //String path = file.getAbsolutePath() + "\\" + certificado;
         String path = "build//web//certificados//"+certificado;
         
         KeyStore ks = KeyStore.getInstance("PKCS12");
        // FileInputStream fis = new FileInputStream(NfeUtil.generatePathToSecurity(path));
         FileInputStream fis = new FileInputStream(path);
         ks.load(fis, senha.toCharArray());
    
         Enumeration aliasesEnum = ks.aliases();
         String alias = "";
         while (aliasesEnum.hasMoreElements()) {
             alias = (String) aliasesEnum.nextElement();
             if (ks.isKeyEntry(alias)) {
                 break;
             }
         }
    
         KeyStore.PrivateKeyEntry keyEntry =
                 (KeyStore.PrivateKeyEntry) ks.getEntry(alias,
                 new KeyStore.PasswordProtection(senha.toCharArray()));
    
         X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
         KeyInfoFactory kif = fac.getKeyInfoFactory();
         List x509Content = new ArrayList();
         x509Content.add(cert);
         X509Data xd = kif.newX509Data(x509Content);
         KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
    
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         dbf.setNamespaceAware(true);
         DocumentBuilder db = dbf.newDocumentBuilder();
         ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes());
         Document doc = db.parse(is);
    
         DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());
         XMLSignature signature = fac.newXMLSignature(si, ki);
         signature.sign(dsc);
    
         StringWriter sw = new StringWriter();
         TransformerFactory tf = TransformerFactory.newInstance();
         Transformer trans = tf.newTransformer();
         trans.transform(new DOMSource(doc), new StreamResult(sw));
         result = sw.getBuffer().toString();
    
     } catch (ClassNotFoundException ex) {
         ex.printStackTrace();
         return null;
     } catch (InstantiationException ex) {
         ex.printStackTrace();
         return null;
     } catch (IllegalAccessException ex) {
         ex.printStackTrace();
         return null;
     } catch (TransformerConfigurationException ex) {
         ex.printStackTrace();
         return null;
     } catch (TransformerException ex) {
         ex.printStackTrace();
         return null;
     } catch (MarshalException ex) {
         ex.printStackTrace();
         return null;
     } catch (XMLSignatureException ex) {
         ex.printStackTrace();
         return null;
     } catch (UnrecoverableEntryException ex) {
         ex.printStackTrace();
         return null;
     } catch (CertificateException ex) {
         ex.printStackTrace();
         return null;
     } catch (KeyStoreException ex) {
         ex.printStackTrace();
         return null;
     } catch (InvalidAlgorithmParameterException ex) {
         ex.printStackTrace();
         return null;
     } catch (NoSuchAlgorithmException ex) {
         ex.printStackTrace();
         return null;
     } catch (ParserConfigurationException ex) {
         ex.printStackTrace();
         return null;
     } catch (SAXException ex) {
         ex.printStackTrace();
         return null;
     } catch (IOException ex) {
         ex.printStackTrace();
         return null;
     }
     return result;
    

    }
    }[/code]

Segue o codigo que cria o XML…

[code]package br.com.cienci.nfe.parser;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
*

  • @author Ciro S. Santos
    */
    public abstract class XmlCreator {

    public String generateStringFromXml(Document document) {

     TransformerFactory tf = TransformerFactory.newInstance();
     Transformer transformer;
     DOMSource dSource = new DOMSource(document);
     StringWriter sw = new StringWriter();
     String result = "";
    
     try {
         transformer = tf.newTransformer();
         transformer.transform(dSource, new StreamResult(sw));
         result = sw.getBuffer().toString();
    
     } catch (TransformerConfigurationException e2) {
         e2.printStackTrace();
         return null;
     } catch (TransformerException e) {
         e.printStackTrace();
         return null;
     }
     return result;
    

    }

    public boolean validateXmlFromSchema(String xml, String schema) {

     try {
         //File fileXmlShemas = new File("src\\xmlSchemas");
        //String pathXmlSchemas = fileXmlShemas.getAbsolutePath() + "\\" + schema; 
         String pathXmlSchemas ="build//web//certificados//"+schema;
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         dbf.setNamespaceAware(true);
         DocumentBuilder parser = dbf.newDocumentBuilder();
         ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes());
         Document document = parser.parse(is);
    
         SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
         //Source schemaFile = new StreamSource(new File(NfeUtil.generatePathToSchemas(pathXmlSchemas)));
         Source schemaFile = new StreamSource(new File(pathXmlSchemas));
         Schema newSchema = factory.newSchema(schemaFile);
         Validator validator = newSchema.newValidator();
         validator.validate(new DOMSource(document));
    
     } catch (SAXException ex) {
         System.err.println("SAX");
         ex.printStackTrace();
         return false;
     } catch (IOException ex) {
         System.err.println("IO");
         ex.printStackTrace();
         return false;
     } catch (ParserConfigurationException ex) {
         System.err.println("Parser");
         ex.printStackTrace();
         return false;
     }
     return true;
    

    }

    public abstract String generateXml(String cnpjSender, String cnpjRatepayer);
    }
    [/code]

Segue a classe que gera o XML para o cancelamento de NF e

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.cienci.nfe.parser;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Attr;
import org.xml.sax.SAXException;

/**
 *
 * @author Elton Cunha
 */
public class PedidoDeCancelamentoNFExml extends XmlCreator {
//public String generateXml(String cnpjRemetente, boolean transacao, String inscricaoPrestador, String numeroNfe) throws Exception {

    public String generateXml(String cnpjRemetente, String inscricaoPrestador, String numeroNfe) throws Exception {

        String result = "";

        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);//ACEITA PARAMETRO

            DocumentBuilder dBuilder = factory.newDocumentBuilder();
            Document document = (Document) dBuilder.newDocument();

            // gera o elemento raiz 
            Element root = document.createElementNS("http://www.prefeitura.sp.gov.br/nfe", "PedidoCancelamentoNFe");
            root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
            root.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
            document.appendChild(root);

            //gera o cabeçalho, dentro do elemento raiz  Exemplo: <Cabecalho Versao="1" xmlns="">
            Element cabecalho = document.createElement("Cabecalho");
            Attr versao = document.createAttribute("Versao");
            versao.setValue("1");
            cabecalho.setAttributeNode(versao);
            cabecalho.setAttribute("xmlns", "");
            root.appendChild(cabecalho);


            // cria os dados dentro da tag cabeçalho 
            Element remetente = document.createElement("CPFCNPJRemetente");
            Element cnpjR = document.createElement("CNPJ");
            Element transacaoElement = document.createElement("transacao");
            transacaoElement.setTextContent("true");
            cnpjR.setTextContent(validaCNPJ(cnpjRemetente));
            remetente.appendChild(cnpjR);
            cabecalho.appendChild(remetente);
            cabecalho.appendChild(transacaoElement);

            //gera os detalhes, dentro do elemento raiz
            Element detalhe = document.createElement("Detalhe");
            detalhe.setAttribute("xmlns", "");
            root.appendChild(detalhe);

            //cria os elementos dentro da tag detalhes
            Element chaveNfe = document.createElement("ChaveNFe");
            Element inscricaoPrest = document.createElement("InscricaoPrestador");
            inscricaoPrest.setTextContent(validaInscricaoPrestador(inscricaoPrestador));
            Element numeroNF = document.createElement("NumeroNFe");
            numeroNF.setTextContent(validaNumeroNotaFiscal(numeroNfe));
            chaveNfe.appendChild(inscricaoPrest);
            chaveNfe.appendChild(numeroNF);
            detalhe.appendChild(chaveNfe);

            /*
            // gera a assinatura do arquivo xml
            Element assinatura = document.createElement("Signature");
            assinatura.setAttribute("xmlns", "http://www.w3.org/2000/09/xmldsig#");
            root.appendChild(assinatura);
            
            // insere os dados entre as tags da assinatura 
            Element signedInfo = document.createElement("SignedInfo");
            assinatura.appendChild(signedInfo);
            Element canonicalizationMethod = document.createElement("CanonicalizationMethod");
            canonicalizationMethod.setAttribute("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
            signedInfo.appendChild(canonicalizationMethod);
            Element signatureMethod = document.createElement("SignatureMethod");
            Attr signatureMt = document.createAttribute("Algorithm");
            signatureMt.setValue("http://www.w3.org/2000/09/xmldsig#rsa-sha1");
            signatureMethod.setAttributeNode(signatureMt);
            signedInfo.appendChild(signatureMethod);
            
            Element reference = document.createElement("Reference");
            reference.setAttribute("URI", "");
            signedInfo.appendChild(reference);
            
            Element transforms = document.createElement("Transforms");
            reference.appendChild(transforms);
            
            Element transform = document.createElement("Transform");
            transform.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature");
            transforms.appendChild(transform);
            
            Element transform2 = document.createElement("Transform");
            transform2.setAttribute("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
            transforms.appendChild(transform2);
            
            Element digestMethod = document.createElement("DigestMethod");
            digestMethod.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
            reference.appendChild(digestMethod);
            
            Element digestVal = document.createElement("DigestValue");
            digestVal.setTextContent(digestValue);
            reference.appendChild(digestVal);
            
            Element signatureVal = document.createElement("SignatureValue");
            signatureVal.setTextContent(signatureValue);
            assinatura.appendChild(signatureVal);
            
            Element keyInfo = document.createElement("KeyInfo");
            assinatura.appendChild(keyInfo);
            
            Element x509Data = document.createElement("X509Data");
            keyInfo.appendChild(x509Data);
            
            Element x509Certificate = document.createElement("X509Certificate");
            x509Certificate.setTextContent(assinaturaDigital);
            x509Data.appendChild(x509Certificate);
            
             */







            result = this.generateStringFromXml(document);


            if (result != null) {
                System.out.println("XML gerado");
                return result;

            } else {
                System.out.println("Erro ao gerar XML");
                return null;
            }

        } catch (ParserConfigurationException ex) {
            ex.printStackTrace();
            return null;
        }

    }

    public String validaCNPJ(String cnpj) throws Exception {
        long cnpj2 = 0;
        String auxCNPJ = null;
        try {
            if (cnpj != null) {
                if (cnpj.length() != 14) {
                    throw new Exception("Valor invalido, verifique a quantidade de digitos do C.N.P.J obs. Digite apenas numeros");
                } else if (cnpj.length() == 14) {
                    cnpj2 = Long.parseLong(cnpj);
                }
            }
            return auxCNPJ = String.valueOf(cnpj2);
        } catch (Exception e) {
            throw new Exception("Erro:" + e.getMessage());
        }

    }

    public String validaTransacao(boolean transacao) throws Exception {

        String transacaoAux = null;
        if (transacao == true) {

            transacaoAux = "true";
        } else {
            throw new Exception("O valor da transação não poder falso");
        }
        return transacaoAux;
    }

    public String validaInscricaoPrestador(String inscPrestador) throws Exception {

        long inscricaoPrest = 0;
        String auxIscPrestador = null;
        try {
            if (inscPrestador != null) {
                if (inscPrestador.length() != 8) {
                    throw new Exception("Valor invalido, verifique a quantidade de digitos da Inscrição do Prestador obs. Digite apenas numeros");
                } else if (inscPrestador.length() == 8) {
                    inscricaoPrest = Long.parseLong(inscPrestador);
                }
            }
            return auxIscPrestador = String.valueOf(inscricaoPrest);
        } catch (Exception e) {
            throw new Exception("Erro: " + e.getMessage());
        }

    }

    public String validaNumeroNotaFiscal(String numeroNF) throws Exception {

        long numberNF = 0;
        String auxNumeroNF = null;
        try {
            if (numeroNF != null) {
                if (numeroNF.length() != 12) {
                    throw new Exception("Valor invalido, verifique a quantidade de digitos da Nota Fiscal  obs. Digite apenas numeros");
                } else if (numeroNF.length() == 12) {
                    numberNF = Long.parseLong(numeroNF);
                }
            }
            return auxNumeroNF = String.valueOf(numeroNF);
        } catch (Exception e) {
            throw new Exception("Valor invalido, digite apenas numeros " + e.getMessage());
        }
    }

    @Override
    public String generateXml(String cnpjSender, String cnpjRatepayer) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getCancelamento(String xmlResponse) {

        String im = "";

        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder = null;
            Document doc = null;

            builder = factory.newDocumentBuilder();
            ByteArrayInputStream is = new ByteArrayInputStream(xmlResponse.getBytes());
            doc = builder.parse(is);
            im = doc.getElementsByTagName("Sucesso").item(0).getChildNodes().item(0).getNodeValue();

            String verificarTranscao = im;

            if (verificarTranscao.equals(im)) {
                verificarTranscao = "true";
            }


        } catch (ParserConfigurationException ex) {
            ex.printStackTrace();
            im = null;
        } catch (SAXException ex) {
            ex.printStackTrace();
            im = null;
        } catch (IOException ex) {
            ex.printStackTrace();
            im = null;
        }
        return im;
    }
}

Segue a classe responsavel, por mesclar o XML com a assinatura:

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.cienci.nfe.rfc;

import br.com.cienci.nfe.dao.DaoFactory;
import br.com.cienci.nfe.enquiry.WebServiceEnquiry;
import br.com.cienci.nfe.modelo.CertificadoDigital;
import br.com.cienci.nfe.parser.PedidoDeCancelamentoNFExml;
import br.com.cienci.nfe.signature.DigitalSignature;
import java.util.List;

/**
 *
 * @author Elton Cunha
 */
public class PedidoDeCancelamentoWS {

    private static final String JKS = "nfe.jks";
    private static final String JKS_PASS = "cienciCert";
    private static final String REQUEST_SCHEMA = "PedidoCancelamentoNFe_v01.xsd";
    private static final String SCHEMA_RESPONSE = "RetornoCancelamentoNFe_v01.xsd";
    private static final String SENDER = "08866633000199";
    private PedidoDeCancelamentoNFExml cancelamentoXml;
    private DigitalSignature signature;
    private WebServiceEnquiry enquiry;

    public PedidoDeCancelamentoWS() {
        this.cancelamentoXml = new PedidoDeCancelamentoNFExml();
        this.signature = new DigitalSignature();
        this.enquiry = new WebServiceEnquiry();
    }

    public String getCancelamento(String cnpjContribuinte, String numeroNFE, String inscricaoDoPrestador) throws Exception {

        String[] privateKey = this.getPrivateKey(cnpjContribuinte);
        String xmlGenerated = "", result = "", xmlSigned = "", responseXml = "";

        xmlGenerated = cancelamentoXml.generateXml(cnpjContribuinte, inscricaoDoPrestador, numeroNFE);

        if (xmlGenerated != null) {
            System.out.println("XML String generated with success!!");
            System.out.println(xmlGenerated);
            System.out.println("-------------------------------------------------------------");

            xmlSigned = signature.sign(xmlGenerated, privateKey[0], privateKey[1]);
            if (xmlSigned != null) {
                System.out.println("New XML signed!");
                System.out.println(xmlSigned);
                System.out.println("-------------------------------------------------------------");
                if (cancelamentoXml.validateXmlFromSchema(xmlSigned, REQUEST_SCHEMA)) {
                    System.out.println("XML validated!!");

                    responseXml = enquiry.enquiryCnpj(xmlSigned, privateKey[0], privateKey[1], JKS, JKS_PASS);
                    if (responseXml != null) {
                        System.out.println("Enquiry done with success!!");
                        System.out.println(responseXml);
                        System.out.println("-------------------------------------------------------------");
                        if (cancelamentoXml.validateXmlFromSchema(responseXml, SCHEMA_RESPONSE)) {
                            System.out.println("Response file validated with success!!");

                            result = cancelamentoXml.getCancelamento(responseXml);
                            if (result != null) {
                                System.out.println("Municipal Inscription: " + result);
                                return result;
                            } else {
                                System.out.println("Error on generate Municipal Inscription!");
                                return null;
                            }
                        } else {
                            System.out.println("Problems found in validate response file!!");
                            return null;
                        }
                    } else {
                        System.out.println("Error in Enquiry!!");
                        return null;
                    }
                } else {
                    System.out.println("Problems on validade xml file!!");
                    return null;
                }
            } else {
                System.out.println("Problems in generated digital signature!!");
                return null;

            }
        } else {
            System.out.println("Problems in created xml String!!");
            return null;
        }

       
    }

    private String[] getPrivateKey(String ratepayerCnpj) {

        String[] array = new String[2];
        DaoFactory factory = new DaoFactory();
        List<CertificadoDigital> listAttest = factory.getCertificadoDigitalDao().listaTudo();
        CertificadoDigital attest = new CertificadoDigital();

        for (CertificadoDigital cd : listAttest) {
            if (cd.getCnpj().equals(ratepayerCnpj)) {
                attest = cd;
                break;
            }
        }

        String[] split = attest.getPath().split("/");
        array[0] = split[split.length - 1];
        array[1] = attest.getSenha();
        return array;
    }
}

Obrigado pela ajuda

problema solucionado… a senha do certificado estava incorreta…

Obrigado pela ajuda.