[Resolvido] Certificado A3 via WEB - Assina mas não consulta status serviço

Estou enviando certificado A1 via web corretamente porém com A3 consigo assinar mas a partir daí não consegui avançar.

Assino com:

    private void assinar(String arquivoXML, String arquivoCertificado,
            String password, String operacao) throws Exception {

        /*
         * operacao '1' - NFE '2' - CANCELAMENTO '3' - INUTILIZACAO
         */
        String tag = "";
        if (operacao.equals("1")) {
            tag = "infNFe";
        } else if (operacao.equals("2")) {
            tag = "infCanc";
        } else if (operacao.equals("3")) {
            tag = "infInut";
        }

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(false);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document docs = builder.parse(new File(arquivoXML));

        NodeList elements = docs.getElementsByTagName(tag);

        Element el = (Element) elements.item(0);
        String id = el.getAttribute("Id");

        // Cria um DOM do tipo XMLSignatureFactory que será utilizado
        // para gerar a assinatura envelopada (enveloped signature)
        String providerName = System.getProperty(PROVIDER_NAME,
                PROVIDER_CLASS_NAME);

        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
                (Provider) Class.forName(providerName).newInstance());

        // Define os algoritmos de transformação
        ArrayList transformList = new ArrayList();
        TransformParameterSpec tps = null;
        Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED,
                tps);
        Transform c14NTransform = fac.newTransform(C14N_TRANSFORM_METHOD, tps);
        transformList.add(envelopedTransform);
        transformList.add(c14NTransform);

        // Cria o objeto Reference
        Reference ref = fac.newReference("#" + id, fac.newDigestMethod(
                DigestMethod.SHA1, null), transformList, null, null);

        // Cria o elemento SignedInfo
        SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(
                CanonicalizationMethod.INCLUSIVE,
                (C14NMethodParameterSpec) null), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                Collections.singletonList(ref));

        //verifica o tipo de certificado
        KeyStore ks = null;
        if (certificado.getTipo().equalsIgnoreCase("a1")) {

            // Carrega o KeyStore e obtem a chave do certificado
            ks = KeyStore.getInstance("PKCS12");
            ks.load(new FileInputStream(arquivoCertificado), password.toCharArray());

        } else {

            Provider p = new sun.security.pkcs11.SunPKCS11(arquivoCertificado);
            Security.addProvider(p);

            ks = KeyStore.getInstance("pkcs11", p);
            try {
                ks.load(null, password.toCharArray());
            } catch (IOException e) {
                throw new Exception("Senha do Certificado Digital incorreta ou Certificado inválido.");
            }

        }

        Enumeration aliasesEnum = ks.aliases();
        String alias = "";
        while (aliasesEnum.hasMoreElements()) {
            alias = (String) aliasesEnum.nextElement();
            if (ks.isKeyEntry(alias)) {
                break;
            }
        }

        if (alias.isEmpty()) {
            throw new Exception(" Alias não reconhecido!");
        }

        KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(password.toCharArray()));

        // Instancia um certificado do tipo X509
        X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

        // Cria o elemente KeyInfo contendo a X509Data.
        KeyInfoFactory kif = fac.getKeyInfoFactory();
        List x509Content = new ArrayList();
        x509Content.add(cert);
        X509Data xd = kif.newX509Data(x509Content);
        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

        // Instancia o documento que será assinado
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);

        Document doc = dbf.newDocumentBuilder().parse(
                new FileInputStream(arquivoXML));


//        //Remove a tag xmlns:ns2 que o jaxb cria e a sefaz seta como nao necessaria
//        doc.getDocumentElement().removeAttribute("xmlns:ns2");


        // Cria o DOMSignContext especificando a chave e o nó pai
        DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());

        // Cria a XMLSignature, mas não assina ainda
        XMLSignature signature = fac.newXMLSignature(si, ki);

        // Empacota (marshal), gera e assina
        signature.sign(dsc);

        // Arquivo novo assinado
        OutputStream os = new FileOutputStream(arquivoXML);
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os));


        // Encontra o elemente Signature
        NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS,
                "Signature");

        if (nl.getLength() == 0) {
            throw new Exception("Não foi possível encontrar o elemente Signature");
        }

        // Cria um DOMValidateContext
        DOMValidateContext valContext = new DOMValidateContext(
                new X509KeySelector(ks), nl.item(0));

        // Dsempacota (unmarshal) a XMLSignature
        XMLSignature signatures = fac.unmarshalXMLSignature(valContext);

        // Valida a XMLSignature.
        boolean coreValidity = signatures.validate(valContext);

        // Checa o status da validação
        if (!coreValidity) {
            throw new Exception("Falha na Assinatura!");
        }
    }

Consulto status do serviço com o código abaixo mas retorna org.apache.axis2.AxisFault: Error signing certificate verify

rivate static boolean StatusServico() {

        //Autentica com o ambiente
        Ambiente.configAmbiente(UtilNFe.getCertificado());

        //Monta xml da pesquisa
        String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<consStatServ versao=\"2.00\" xmlns=\"http://www.portalfiscal.inf.br/nfe\">"
                + "<tpAmb>" + ConfiguracaoGlobal.getConfiguracaoGlobal(estab).getNfe_tpAmb() + "</tpAmb>"
                + "<cUF>43</cUF>"
                + "<xServ>STATUS</xServ>"
                + "</consStatServ>";

        try {
            //Trata o ws
            NfeStatusServico2Stub.setAmbiente(ConfiguracaoGlobal.getConfiguracaoGlobal(estab).getNfe_tpAmb());
            NfeStatusServico2Stub stub = new NfeStatusServico2Stub();
            NfeStatusServico2Stub.NfeDadosMsg dados = new NfeStatusServico2Stub.NfeDadosMsg();

            OMElement el = AXIOMUtil.stringToOM(XML);
            dados.setExtraElement(el);

            NfeStatusServico2Stub.NfeCabecMsg cab = new NfeStatusServico2Stub.NfeCabecMsg();
            cab.setVersaoDados("2.00");
            cab.setCUF("43");
            NfeStatusServico2Stub.NfeCabecMsgE cabE = new NfeStatusServico2Stub.NfeCabecMsgE();
            cabE.setNfeCabecMsg(cab);

            //Executa consulta no ws
            String retorno = stub.nfeStatusServicoNF2(dados, cabE).getExtraElement().toString();

            //System.out.println(retorno);

            //Executa o unmarshal do retorno
            JAXBContext context = JAXBContext.newInstance("nfe2.beans.retConsStatServ");
            Unmarshaller unmarshaller = context.createUnmarshaller();
            JAXBElement<TRetConsStatServ> retcanc = (JAXBElement<TRetConsStatServ>) unmarshaller.unmarshal(new StringReader(retorno));

            //Retorna sucesso ou falha
            if (retcanc.getValue().getCStat().equals("107")) {
                return true;
            } else {
                error = retcanc.getValue().getXMotivo();
                DialogEnvio.setInformacoes(error);
                return false;
            }


        } catch (XMLStreamException | RemoteException | JAXBException e) {
            error = e.toString();
            DialogEnvio.setInformacoes(error);
            Logger.getLogger(ConexaoUtil.class.getName()).log(Level.SEVERE, null, e);
        }

        return false;
    }
public static void configAmbiente(Certificado cert) {

        KeyStore ks = null;

        try {

            if (cert.getTipo().equalsIgnoreCase("a1")) {
                InputStream entrada = new FileInputStream(cert.getLocal());
                ks = KeyStore.getInstance("pkcs12");
                try {
                    ks.load(entrada, cert.getSenha().toCharArray());
                } catch (IOException e) {
                    DialogEnvio.setInformacoes("Senha do Certificado Digital A1 incorreta ou Certificado inválido.");
                    DialogEnvio.setImagem(DialogEnvio.atencao);
                    DialogEnvio.setTexto("ERRO");
                }
            } else if (cert.getTipo().equalsIgnoreCase("a3")) {

                Provider p = new sun.security.pkcs11.SunPKCS11(cert.getLocalToken());
                Security.addProvider(p);

                ks = KeyStore.getInstance("pkcs11", p);
                try {
                    ks.load(null, cert.getSenha().toCharArray());
                } catch (IOException e) {
                    DialogEnvio.setInformacoes("Senha do Certificado Digital A3 incorreta ou Certificado inválido.");
                    DialogEnvio.setImagem(DialogEnvio.atencao);
                    DialogEnvio.setTexto("ERRO");
                }

            }

            String alias = null;
            Enumeration<String> al = ks.aliases();
            while (al.hasMoreElements()) {
                alias = al.nextElement();
            }

            

        } catch (Exception e) {
            System.out.println(e);
        }

    }

Qual pode ser o erro ?

Resolvido criando KeyStore estático e lido única vez na aplicação.

1 curtida

como vc fez para funcionar, estou com um problema igual ou parecido,
tenho uma aplicação que faz pesquisa com o certificado a1 e se o cliente quiser mudar o certificado
pode configurar, só que quando ele muda o certificado não funciona mais ele fica reconhecendo o certificado antigo
estou limpando:

System.clearProperty(“javax.net.ssl.keyStore”);
System.clearProperty(“javax.net.ssl.keyStorePassword”);
System.clearProperty(“javax.net.ssl.trustStore”);

mas não funciona.