Jump to content
Luiz Paulo Franz

Assinatura digital com PHP

Recommended Posts

Bom dia, estou enfrentando dificuldades na geração de Nfs-e aqui para minha cidade, antes estava com problemas nos web-services, mas isso foi contornado, agora o problema está na assinatura digital. Usei como base o projeto http://www.nfephp.org/ para o desenvolvimento da minha nota, inclusive a função para assinar o XML, porém quando tento validar meu XML gerado no site da receita sempre informa assinatura digital inválida, a questão é que eu não sei o que estou fazendo de errado. Vou colar o XML que estou tentando validar, sei que o problema pode estar no DigestValue ou algo assim, mas não custa tentar.

 

<e:EnviarLoteRpsEnvio xmlns:e="http://www.betha.com.br/e-nota-contribuinte-ws">
<LoteRps Id="000000000000018">
<NumeroLote>000000000000018</NumeroLote>
<Cnpj>00704877000163</Cnpj>
<InscricaoMunicipal>6667</InscricaoMunicipal>
<QuantidadeRps>1</QuantidadeRps>
<ListaRps>
<Rps>
<InfRps Id="Rps43210000000000000060070487700016330042013">
<IdentificacaoRps>
<Numero>000000000000006</Numero>
<Serie>0413</Serie>
<Tipo>1</Tipo>
</IdentificacaoRps>
<DataEmissao>2013-04-30T08:57:49</DataEmissao>
<NaturezaOperacao>1</NaturezaOperacao>
<OptanteSimplesNacional>2</OptanteSimplesNacional>
<IncentivadorCultural>2</IncentivadorCultural>
<Status>1</Status>
<Servico>
<Valores>
<ValorServicos>32.50</ValorServicos>
<IssRetido>2</IssRetido>
<ValorIss>1.30</ValorIss>
<BaseCalculo>32.50</BaseCalculo>
<Aliquota>0.04</Aliquota>
<ValorLiquidoNfse>31.20</ValorLiquidoNfse>
</Valores>
<ItemListaServico>10.05</ItemListaServico>
<Discriminacao>
HONORARIOS DA PARCELA 05/36 DO CONTRATO DE LOCACAO 3669
</Discriminacao>
<CodigoMunicipio>4321</CodigoMunicipio>
</Servico>
<Prestador>
<Cnpj>00704877000163</Cnpj>
<InscricaoMunicipal>6667</InscricaoMunicipal>
</Prestador>
<Tomador>
<IdentificacaoTomador>
<CpfCnpj>
<Cnpj>49709496/000166</Cnpj>
</CpfCnpj>
</IdentificacaoTomador>
<RazaoSocial>BELFIN LTDA</RazaoSocial>
<Endereco>
<Endereco>RUA ALMIRANTE BARROSO,85</Endereco>
<Bairro>CENTRO</Bairro>
<Uf>SC</Uf>
<Cep>89900000</Cep>
</Endereco>
</Tomador>
</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="#000000000000018">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>y85/S/h06D4tpYIz1aVOK4MhjMU=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
GzJRFnzUMrzTukTGiaHKXe+gO4inIRaIN/OX9hRy+m/7nfyY573uyoYCVm3A73wjGuNQahSqB6s8jGcFEcXmvg4iBPARi5nylofK1REC8NE5fBZJ06ci93YOK7Xpn8aqSJo5I+S/5+yi+aBCoLhChzusVp+DJqW05alD9zoG8bgpqpIbuQsq6DKBdSenytQFSFz8EYGBUuCxV/LgEctJdHq3AODnCwE8M3jv+CPFdPnXXKVOWCTNi5O43vaKUj3dguMzamzMmCJoZqQ4DVMS7Ta10s1kyxJQjnaa67ZW15I7oqOn4G370k6z5dpMeLxhyATdWfqD35NTwGAIQORL3Q==
</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>
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
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</e:EnviarLoteRpsEnvio>

Se alguém tiver alguma ideia de o que pode estar causando esse erro, ou já passou por essa dificuldade, se puder ajudar agradeço. Também, caso tenha algum link para leitura complementar sobre assinaturas digitais que possam me ajudar, ficarei feliz acessá-los.

 

Obrigado pela atenção.

 

Share this post


Link to post
Share on other sites

estou com o mesmo problema, qual a perte do xml que tenho q validar,

outra coisa como faço isso em meu sitema php?

Share this post


Link to post
Share on other sites

Olá, se você está usando o web service da Betha, você deve assinar as tags InfRps separadamente, depois juntar tudo e assinar tudo junto na tag LoteRps, eu me baseei no projeto http://www.nfephp.org/, baxa ele e da uma estudada nos fontes, a parte de assinatura eu peguei daí e alterei pra se encaixar aos padrões da Betha, espero ter ajudado, até mais.

Share this post


Link to post
Share on other sites

fiz a minha conta no e-gov.betha.com.br

e pediu um nimero de serial, onde consigo esse numero de serial?



cara por que assim eu to meio que perdido nesse assunto,

fui colocar a prefeitura nesse site que você me passo, so que não mostro a de fortelaza,

Share this post


Link to post
Share on other sites

Você precisa primeiramente do manual para gerar o arquivo XML da Betha, esse manual está disponível aqui:

 

https://e-gov.betha.com.br/e-nota/login.faces

 

Nessa página, procure por "Integração com sistema", onde poderá baixar os manuais para gerar o XML, juntamente com seus schemas para validá-los se assim desejar, eu não fiz isso (na verdade fiz mas não validava, fazer o que), mas o sistema da Betha aceita normalmente as requisições.

E em "Ambiente de Testes" você pode criar uma conta em um ambiente de testes, que simula com perfeição o ambiente de produção.

 

Com isso, você já consegue dar um start, eu aconselho você usar o programa soapUI para velidar seus XMLs, é muito bom, pois se você colar o endereço do WSDL, ele já gera um XML exemplo da requisição.

Como havia dito, eu usava PHP, e as funções nativas para consumo de webservices não funcionavam no caso da Betha, isso você vai ter de identificar, se você usa PHP, aconselho usar a biblioteca Curl para fazer isso.

 

Outra coisa importante de se estudar é assinatura digital, caso não saiba, aqui vai alguma coisa que pode lhe nortear no assunto.

 

espero ter ajudado, até mais.

Share this post


Link to post
Share on other sites

pessoal sou novo nesta parte de emissão de NFS ainda estou nos primeiros passos . mas minha mior duvida por enquanto e a seguinte .

 

como consigo fazer a assinatura na no xml quais funções do php usar ?

preciso de alguma coisa a mais ?

alguem poderia dar uma luz ai por favor ?

Share this post


Link to post
Share on other sites

Da uma olhada nesse projeto, ele tem um exemplo de como fazer assinatura digital em PHP. http://www.nfephp.org/

 

Aki vai um resumão que eu fiz sobre certificados digitais, assinaturas digitais, criptografia e essas coisas...

 

*Arquivos p12 e pfx: (certificados digitais) São a mesma coisa.
Eles contém a chave pública e a chave privada no mesmo documento criptografado e protegido por senha,
dele, podemos obter a chave privada e a chave publica, também certificado digital, dados esses criptografados em X509.
 
*X509: Criptografia usada para os arquivos .pem, usada também nos dados contidos nos arquivos .pfx, no PHP, ao extrairmos os dados de um certificado digital no formato .pfx com a função openssl_pkcs12_read(), as informações são apresentadas com a criptografia x509, essa função retorna um array com a chave publica e com o certificado, criptografados nesse padrão, para ler as informações contidas, usamos a função openssl_x509_parse(), que decripta os dados. Obs: Apenas decripta os dados do certificado.
 
*.pem: Formato de arquivo definido para conter a chave-pública, ou pode conter ambas as chaves, também o certificado digital.
 
*Certificado Digital: É a chave pública com algumas informações a mais, inseridas pela unidade certificadora,
o certificado digital assegura que essa chave pública é sua mesmo.
 
__________________________________________________________________________________________________________
 
Softwares de emissão de NFe e NFSe usam certificados A1.
 
Para assinaturas via software, é extremamente recomendável o certificado A1, pois este pode ser instalado em quantas maquinas desejarmos, inclusive seu servidor apache, já o A3 precisa do Token, que é uma espécie de pendrive, contendo as chaves do certificado, assim sendo, se seu software fizer assinatura digital para 500 clientes, você deve ter 500 Tokens conectados à ele, sem falar que precisaria de um servidor com 500 portas USB ^^. Sendo assim, softwares de emissão NFe ou NFSe geralmente dão suporte apenas a certificados do tipo A1. Certificado digital do Tipo A1 vem em um arquivo pfx ou p12.
__________________________________________________________________________________________________________
 
CERTIFICADOS DIGITAIS EM PHP
Utilizando o PHP, temos algumas funções que nos auxiliam a extrair as chaves de certificados tipo A1, que utilizam arquivos .pfx ou p12. Para isso precisamos da senha do arquivo em questão. Tendo a senha em mãos, usamos a função openssl_pkcs12_read() para abrir o arquivo pfx ou p12 e extrair os dados do certificado, depois usamos a função openssl_x509_read() que monta um array com as informações criptografadas no padrão X509, depois disso, conseguimos ler os dados do certificado com a função openssl_x509_parse(), essa função decripta os dados apenas do campo ['cert'] do array retornado. Nesse campo decriptado, temos informações sobre o dono do certificado, datas limites entre outras.
__________________________________________________________________________________________________________
 
ASSINATURA DIGITAL
Em alguns casos, como na emissão das NFS-e por exemplo, as chaves públicas com certificados digitais são usadas apenas para comprovar quem escreveu o documento, e manter as informações sem alterações de terceiros. Para esse processo, podem ser usados dois mecanismos, (Message Autentication Code)-MAC e assinaturas digitais. Usaremos assinaturas digitais.
Assinatura digital é um tipo expecífico de MAC. Para assinar um documento sem criptorafia, é usado um (Message Digest)-MD, como o MD5 por exemplo, para gerar um hash do conteúdo do documento, depois disso, criptografa-se o hash com a chave privada do emitente, e esse trecho criptografado é apresentado junto ao documento, isso tudo é a assinatura digital.
Para checar os dados, o destinatário deve gerar um hash do documento usando o mesmo MD do emissor, ignorando os dados da assinatura digital que foram acrescidos ao documento, depois decifrar os dados da assinatura com a chave publica do emitente, e comparar os hash's.
Para ser possível que um documento ou assinatura sejam adulteradas e não sejam detectadas, o atacante deve ter acesso a chave privada do emissor.
Assinaturas digitais são verificadas usando a chave publica do emissor. Documentos assinados digitalmente, não são criptografados, apenas a própria assinatura é criptografada. A assinatura é um MD, como MD5 por exemplo, tornando o processo muito mais rápido.
Assim sendo, assinaturas digitais podem ser geradas e anexadas aos documentos, e armazenadas em qualquer lugar, sem se preocupar com a segurança do sistena que as armzena, tendo em vista que o atacante precisa da chave privada para alterar de forma eficiente o documento.
__________________________________________________________________________________________________________
 
CRIPTOGRAFIA ASSIMÉTRICA
Também conhecida como criptografia de chave pública.
O padrão de criptografia assimétrica que a receita federal do Brasil adotou é o RSA. Um dos mais completos existentes. As chaves são diferentes porém são relacionadas, os dados criptografados com a chave privada só poderão ser decifrados com a chave pública, e os dados criptografados com a chave pública, só serão decifrados com a chave privada.
__________________________________________________________________________________________________________
 
CERTIFICADOS DIGITAIS NO BRASIL
 
Para entender certificados digitais, recomenda-se essa leitura:
 
Qual certificado comprar A1 ou A3 ?
 
Os certificados são os mesmos. A diferença é a mídia onde estarão armazenados.
O A1 é em formato de arquivo no padrão .p12 ou .pfx.
O A3 é armazenado no token ou pendrive.
 
O que faz a diferença é que o A1 pode ser criado e instalado a primeira vez em um computador e depois exportado para quantos computadores você desejar. Bem como salvá-lo em qualquer lugar como backup de segurança.
 
Já o A3 só pode ser utilizado em conjunto com o TOKEN. Pois a chave privada é gerada pelo hardware do token e não fica disponível de forma alguma. Tornando assim o certificado praticamente em objeto físico.
 
Portanto sendo o TOKEN um equipamento, ele pode sofrer danos.
Os danos mais comuns que tenho presenciado são os seguintes:
 
Bloquear o token por digitar a senha errada e não saber a senha PUK
Criar as senhas iniciais PIN e PUK (Usuário e Admin) idênticas
Entrar no modo administrador e apagar o certificado
Plugar o TOKEN em USB frontal com cabo invertido e queimá-lo
Quebrar o TOKEN
Molhar o TOKEN
Mas ao comprar o A1 tenho que renovar anualmente?
 
Sim, certificados A1 têm a validade de 01 ano.
Mas você não precisa fazer a validação presencial e nem apresentar a documentação.
Se o certificado ainda não venceu e ainda é válido, basta você renovar on-line.
O processo online de obtenção do certificado é o idêntico ao da aquisição.
 
O preço média da renovação do A1 é de R$120,00.
 
Mas porque eles sempre empurram o A1 para comprar?
 
O A1 custa na média R$150,00 inicialmente e é renovado anualmente.
O A3 custa na média R$400,00 inicialmente e é renovado em três anos.
 
O preço portanto para 3 anos é praticamente o mesmo:
 
A1 = R$ 390,00 (R$150,00 + R$ 120,00 + R$ 120,00)
A3 = R$ 400,00
 
O A1 pode ser instalado e usado independente da quantidade de computadores.
Já o A3 só pode estar em 01 computador por vez para ser usado.
Ou seja, para usar simultâneamente você precisa de 01 TOKEN em cada computador.
 
Outro detalhe está no fato de poder danificar o TOKEN e ter que comprar outro.
Literalmente, pois não poderá renovar sem ele funcionando.
 
Mas e se alguém roubar meu A1?
 
Opções é que não faltam para resolver isso:
 
Revogar o certificado no site do AR que você adquiriu;
Todos os sites pedem senha para serem acessados;
Renovar o certificado junto ao AR antes de expirar;
Solicitar que rastreamento do IP do meliante junto Policia Federal;
Confira nos sites:
 
PRODEMGE: Renovação de Certificado Pessoa Jurídica
PRODEMGE: Revogação
 
Validar assinaturas digitais em XML:

Share this post


Link to post
Share on other sites

Colegas, apos ler e entender o valioso material que consta nessa thread eu ainda estou com algumas duvidas (que o OP provavelmente já conseguiu entender mas infelizmente eu ainda continuo com duvida).

 

Comprei o certificado do tipo A1 para emitir notas fiscais eletronicas na prefeitura aqui de Florianopolis. Já integrei todo o meu sistema com a API da Prefeitura e a forma de gerar a NFe é bem simples: eu realizo um POST contendo um XML e pronto, a Prefeitura gerará a NFe.

 

Minha dúvida é a seguinte: no final do arquivo XML há várias linhas que preciso preencher no formato abaixo. Como que eu gero essas linhas usando PHP e o certificado do tipo A1? Eu procurei bastante na internet e não descobri como que gero essa parte final do arquivo XML.

 

Acredito que vários devs estão passando pelo mesmo problema pois quando ligo no suporte da prefeitura eles dizem que muitas outras pessoas já ligaram pra lá pra saber como se faz isso e eles não sabem como responder e que eu teria que consultar um programador (eu sou um programador, pelo menos acho que sou!) para resolver isso!

OBRIGADO!

 

            <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Sign-4.938194207420864E7">

                <ds:SignedInfo>

                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"/>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <ds:Reference Id="RefElement-3.496850484729869E7" URI="">
                    <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"/>
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                    <ds:DigestValue>KsPAoHg2H0y/wSrrOGRihebcE/g=</ds:DigestValue>
                    </ds:Reference>

                </ds:SignedInfo>

                <ds:SignatureValue Id="SignatureValueID-7.454649528132233E7">
                CkDFTzGt0+vg...==
                </ds:SignatureValue>
                <ds:KeyInfo>

                    <ds:X509Data>

                        <ds:X509IssuerSerial>

                            <ds:X509IssuerName>
                            CN=AC Instituto Fenacon RFB G3, OU=Secretaria da Receita Federal do Brasil - RFB, O=ICP-Brasil, C=BR
                            </ds:X509IssuerName>
                            <ds:X509SerialNumber>1c28f49fd377...</ds:X509SerialNumber>

                        </ds:X509IssuerSerial>

                        <ds:X509Certificate>
                        MIIIPDCCBiSg...
                        </ds:X509Certificate>

                    </ds:X509Data>

                </ds:KeyInfo>

            </ds:Signature>

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.