[Erro] Checando assinatura de NF-e

466 views
Skip to first unread message

Rodrigo Wanderley de Melo Cardoso

unread,
Nov 30, 2011, 1:33:54 PM11/30/11
to nfe...@googlegroups.com
Boa tarde galera,

Já faz um tempo que tento utilizar a função verifySignatureXML(), porém o mesmo não funciona com nenhuma nota que tenho.

O erro retornado é esse: 
Warning: openssl_verify() [function.openssl-verify]: Don't know how to get public key from this private key in C:\Program Files (x86)\EasyPHP-5.3.8.1\www\Nfe.php on line 420

Warning: openssl_verify() [function.openssl-verify]: supplied key param cannot be coerced into a public key in C:\Program Files (x86)\EasyPHP-5.3.8.1\www\Nfe.php on line 420

A pergunta é: preciso ter um certificado digital para verificar uma assinatura em nota de clientes?

Obs: O digest value é retornado corretamente e a variável $conteudoAssinado está retornando o valor encontrado no digest value.
Obs2: O sistema consegue gerar a publickey e faço a comparação se a publickey gerada é a mesma do certificado na nota e o sistema retorna ok.

Alguem mais teve esse problema?

Muito obrigado,

Rodrigo W M Cardoso
Web Developer
Infofisc

Rodrigo Wanderley de Melo Cardoso

unread,
Dec 7, 2011, 10:23:51 AM12/7/11
to nfe...@googlegroups.com
Alguem?

Roberto Leite Machado

unread,
Dec 7, 2011, 1:02:09 PM12/7/11
to nfe...@googlegroups.com
O SSL está instalado nessa maquina ??

além disso eu desconheço esse arquivo Nfe.php !!!!

Roberto


Rodrigo Wanderley de Melo Cardoso

unread,
Dec 7, 2011, 1:08:44 PM12/7/11
to nfe...@googlegroups.com
Como eu disse eu uso apenas algumas funções da classe do NfePHP, como não trabalho com emissão de notas ao meu ver é desnecessário carregar a classe Tools.
Sim, o SSL está instalado, inclusive ele consegue gerar o Resource da chave pública. O erro está na comparação do que foi assinado e do retorno da assinatura.
O digest value gerado é igual o da nota.
Somente a comparação das chaves dá um retorno de erro. Sendo que o {{$ok}} retorna NULL.

    /**
     * verifySignatureXML
     * Verifica correção da assinatura no xml
     * 
     * @version 1.01
     * @package NFePHP
     * @author Bernardo Silva <bernardo at datamex dot com dot br>
     * @param string $conteudoXML xml a ser verificado 
     * @param string $tag tag que é assinada
     * @return boolean false se não confere e true se confere
     */
    public function verifySignatureXML($conteudoXML, $tag){
        $dom = new DOMDocument();
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = false;
        $dom->loadXML($conteudoXML);

        $tagBase = $dom->getElementsByTagName($tag)->item(0);
        
        // validar digest value 
        $tagInf = $tagBase->C14N(false, false, null, null);
        $tagInf = str_replace($retXML, '', $tagInf);
        $digestCalculado = base64_encode(sha1($tagInf, true));
        $digestInformado = $dom->getElementsByTagName('DigestValue')->item(0)->nodeValue;
        if ($digestCalculado != $digestInformado){
            $this->errStatus = true;
            $this->errMsg = "O conteúdo do XML não confere com o Digest Value.\nDigest calculado [{$digestCalculado}], informado no XML [{$digestInformado}].\nO arquivo pode estar corrompido ou ter sido adulterado.\n";
            return false;
        }
        // Remontando o certificado 
        $X509Certificate = $dom->getElementsByTagName('X509Certificate')->item(0)->nodeValue;
        $X509Certificate =  "-----BEGIN CERTIFICATE-----\n".
        $this->__splitLines($X509Certificate)."\n-----END CERTIFICATE-----\n";
        $pubKey = openssl_get_publickey($X509Certificate);
            
        if ($pubKey === false){
            $this->errStatus = true;
            $this->errMsg = "Ocorreram problemas ao remontar a chave pública. Certificado incorreto ou corrompido!!\n";
            return false;
        }                
        // remontando conteudo que foi assinado 
        $conteudoAssinado = $dom->getElementsByTagName('SignedInfo')->item(0)->C14N(false, false, null, null);

// Retirar itens das tags da assinatura da nota 
$conteudoAssinado = str_replace($retXML, '', $conteudoAssinado);
// validando assinatura do conteudo 
$conteudoAssinadoNoXML = $dom->getElementsByTagName('SignatureValue')->item(0)->nodeValue;
$conteudoAssinadoNoXML = base64_decode(str_replace(array("\r", "\n"), '', $conteudoAssinadoNoXML));
$ok = openssl_verify($conteudoAssinado, $conteudoAssinadoNoXML, $pubKey);
if ($ok != 1){
            $this->errStatus = true;
            $this->errMsg = "Problema ({$ok}) ao verificar a assinatura do digital!!";
            return false;
}
        $this->errStatus = false;
        $this->errMsg = "";
        return true;
    } // fim verifySignatureXML

Roberto Leite Machado

unread,
Dec 7, 2011, 2:05:07 PM12/7/11
to nfe...@googlegroups.com
Qual é o retorno da função ?? 
Esses WARNINGS podem ser ignorados se a função retornar os resultados corretos.
 
Estou usando a função, no windows, no Debian, no Ubuntu e não retorna esse erro que você descreve.

Como não consigo replicar o erro fica complicado deterninar o motivo.

Roberto

Rodrigo Wanderley de Melo Cardoso

unread,
Dec 7, 2011, 2:14:01 PM12/7/11
to nfe...@googlegroups.com
Então, ela retorna $this->errStatus = true
                                 $this->errMsg = "Problema  ao verificar a assinatura do digital!!"

E a variável $ok retorna nula

Rodrigo Wanderley de Melo Cardoso

unread,
Dec 7, 2011, 2:16:01 PM12/7/11
to nfe...@googlegroups.com
Informações sobre o SSL

openssl

OpenSSL support enabled
OpenSSL Library Version OpenSSL 1.0.0e 6 Sep 2011
OpenSSL Header Version OpenSSL 0.9.8r 8 Feb 2011


Roberto Leite Machado

unread,
Dec 8, 2011, 4:40:34 AM12/8/11
to nfe...@googlegroups.com
Rodrigo;

O problema pode estar em outra parte do codigo e sem ver e testar seu script em outras maquinas não vai dar para determinar a causa do problema. Mas antes de fazer isso me passe o xml que você usou e acusou o erro, para eu testar em uma das minhas maquinas.

Roberto

Fábio Ananias

unread,
Feb 26, 2013, 12:51:47 PM2/26/13
to nfe...@googlegroups.com
Boa tarde galera, alguém poderia me ajudar na seguinte dúvida:

Eu gostaria de utilizar o método verifySignatureXML para verificar a integridade dos arquivos XML que recebo de meus fornecedores (verificar apenas se o conteúdo do XML bate com sua assinatura digital dele). A finalidade deste método é essa mesmo???

Montei um fonte que contém apenas aquele exemplo de uso que está no assembla, fazendo pequenas alterações:
header('Content-type: text/html; charset=ISO-8859-1');
require_once('/nfephp/libs/ToolsNFePHP.class.php');
$nfe = new ToolsNFePHP;
//path para o arquivo da NFe recebida de terceiros que se quer verificar a validade
$fileNFe = "/xml/215/homag-5668.xml";
if( !$nfe->verifyNFe($fileNFe) ){ ////Utilizei o verifyNFe para fazer o menor número de alterações o possível.
    echo $nfe->errMsg;
} else {
    echo "NFe APROVADA e ValIDA";
}

Em alguns casos eu tenho sucesso com a verificação, e em outros casos não. Porém, nos casos em que não tenho sucesso, quando copio e colo o conteúdo do XML no validador de mensagens do site: https://www.sefaz.rs.gov.br/nfe/nfe-val.aspx , ele me diz que "Assinatura Digital: Válida".

Alguém já teve problema parecido?

Com os 2 XMLs em anexo eu não tive sucesso na validação com essa função. Já no site do SEFAZ RS deu Assinatura Válida.

(A saída abaixo fui eu que alterei na Tools!!! Não procurem por ela no fonte.
 * @package   NFePHP
 * @name      ToolsNFePHP
 * @version   3.0.56
)
Ex.: homag-5668.xml
O Conteúdo do XML não confere com o digest Value.
Calculado:
O4SssJk2gZO7MRn2Uo9X/yK+6cE=
Informado na NF:
ENIL9RisxjymID0ovqQKVTgKEw4=


Obrigado.!!
homag-5668.xml
anvi-12128.xml

Roberto Leite Machado

unread,
Feb 26, 2013, 3:04:22 PM2/26/13
to nfe...@googlegroups.com
Fabio;

Veja o xml tem uma sujeira nele ... talvez no envio o sistema tenha colocado essa sujeira não sei 

<infNFe Id="NFe35110943448687000135550000000121281000153231" versao="&quot;2.00&quot;"

 Ao remover o LIXO ...  a NFe validou !!!

Roberto



--
--
Você recebeu esta mensagem porque está inscrito no Grupo "NFePHP".
Para Postar: nfe...@googlegroups.com
Para Sair do Grupo: nfephp+un...@googlegroups.com
Link: http://groups.google.com.br/group/nfephp?hl=pt-BR
-------
Repositório: https://github.com/nfephp-org/nfephp
---
Você está recebendo esta mensagem porque se inscreveu no grupo "NFePHP" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para nfephp+un...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 



--
___________________________________________
Roberto
Nisi utile est quod facimus, stulta est gloria (Julius Phaedous)

Fábio Ananias

unread,
Feb 26, 2013, 3:13:10 PM2/26/13
to nfe...@googlegroups.com
Muito obrigado Roberto!!!
Vou ver se encontro uma função para remover essa sujeira, pois tenho muuuitos Xmls assim.
Abraço!
Reply all
Reply to author
Forward
0 new messages