Assinatura Digital NF-e

1,809 views
Skip to first unread message

Hu Chia Fo

unread,
Apr 22, 2009, 6:50:38 AM4/22/09
to phpav...@googlegroups.com
Saudações srs. , estou acompanhando as discussões com muito interesse , pois sou novato em PHP.
Estou fazendo testes com scripts usando o NUSOAP sem muito sucesso. O problema é que não sei como tratar o leitor de cartão e os dados do SMART CARD !
Isto é no script tenho :
 
 <?php
require_once('nusoap.php');
//$certFile  = "/localhost/web_service/NF-e/serasa_cer_nfe_64.cer";
//$certFile  = "/localhost/web_service/NF-e/sefaz_sp_homologacao.cer";
$certFile  = "/localhost/web_service/NF-e/certificado.cer";
$pass = "12345678";
//$client = new nusoap_client($url, 'WSDL');
$client = new soapclient($wsdl, true);
//$client->setHTTPProxy('ip', 'porta', 'login', 'senha');
//Caso precise comunicar via proxy
$client->authtype = 'certificate'; 
$client->soap_defencoding = 'UTF-8'; 
$client->certRequest['sslcertfile']= $certFile; 
$client->certRequest['passphrase'] = $pass;
$client->certRequest['verifypeer']=0; 
$client->certRequest['verifyhost']=0; 
$client->certRequest['trace']=1; 
$erro = $client->getError();
echo "<br>Erro: $erro <br>"; 
// chamada do método SOAP
$param = array(
   "nfeCabecMsg" => "<?xml version='1.0'encoding='utf-8'?>
                     <cabecMsg versao='1.02' xmlns='http://www.portalfiscal.inf.br/nfe'>
                     <versaoDados>1.07</versaoDados>
                     </cabecMsg>",
   "nfeDadosMsg" => "<?xml version='1.0' encoding='utf-8'?>
                     <consStatServxmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
                   xmlns:xsd='http://www.w3.org/2001/XMLSchema' versao='1.07'
                      xmlns='http://www.portalfiscal.inf.br/nfe'>
                      <tpAmb>2</tpAmb>
                      <cUF>43</cUF>
                      <xServ>STATUS</xServ>
                      </consStatServ>");
$result = $client->call("nfeStatusServicoNF", $param);
// OPCIONAL : exibe a requisição e a resposta
echo '<h2>Requisição</h2>';
echo '<pre>'.htmlspecialchars($client->request).'</pre>';
echo '<h2>Resposta</h2>';
echo '<pre>'.htmlspecialchars($client->response).'</pre>';
// Exibe mensagens para debug
echo '<h2>Debug</h2>';
echo '<pre>'.htmlspecialchars($client->debug_str).'</pre>';
?>
(O script é só um teste para entender como funciona o acesso a HTTPS e XML !)
 
Esta acusando que o PRIVATE KEY não está acessivel , o que faz sentido uma vez que ao exportar o certificado pelo IE para criar o "certificado.cer" apareceu aviso de que a chave privada não poderia ser exportada por configuração da SERASA.
Assim ao ler o e-mail do Roberto com o private key em arquivo , pergunto :
E quanto a chave privada está em SMART CARD com leitora ? Existe alguma função do PHP ou de alguma LIB para obter o private key do cartão ?
 
Agradeceria muito qualquer orientação
Hu
 
 
 

Roberto L. Machado

unread,
Apr 24, 2009, 8:38:35 AM4/24/09
to phpav...@googlegroups.com
Pessoal;

Evitem o uso de certificados digitais no padrão A3 (validade de 3 anos e vem no smart card ou em um token)

Prefiram o certificado A1 (validade de 1 ano e vem em arquivo eletrônico)

Acessar o smartcard ou o token nem sempre é tarefa fácil (no linux por exemplo) e sempre é mais lento que acessar o certificado diretamente.

Se usar o A1, compre dois certificados com intervalo entre as compras de aproximadamente  6 a 9 meses e monte uma rotina para controlar a validade dos mesmos, esta solução sai mais caro (cerca de R$ 500,00 por ano) mas em termos de flexibilidade é muito melhor.


[]'s

Hu Chia Fo

unread,
Apr 24, 2009, 11:54:51 AM4/24/09
to phpav...@googlegroups.com
Obrigado Roberto pela dica.
O problema é que a empresa já adquiriu o certificado em Smart Card !
Vou continuar tentando e se encontrar solução , posto no grupo.
 
Abraço
Hu

2009/4/24 Roberto L. Machado <roberto...@superig.com.br>

Marcelo Rocha

unread,
Jun 15, 2009, 3:46:54 PM6/15/09
to PHP Avançado
Pessoal, se vocês quiserem (por questão de prazo por exemplo) apenas
gerar o XML da NFe, tenho uma boa notícia para vocês:

RDI anuncia Open NFe
Solução de Código Aberto para Nota Fiscal Eletrônica

Belo Horizonte (12/06/2009) - Com o objetivo de auxiliar as empresas
desenvolvedoras de softwares, a RDI disponibiliza a partir de hoje,
além dos binários, também o código-fonte de seu Servidor de Nota
Fiscal Eletrônica. O antigo NFe Admin 2009 agora passa a se chamar
Open NFe. A idéia é oferecer aos desenvolvedores uma solução de código
aberto (Open Source) que cuide da assinatura, envio e tratamento de
contigência das Notas Fiscais Eletrônicas, além da impressão de DANFE.
O trabalho do desenvolvedor fica restrito a gerar o XML de acordo com
as especificações da Secretaria da Fazenda para o SPED (Sistema
Público de Escrituração Digital). O Open NFe é distribuído sob a
licença GPL.
Mais informações em http://www.rochadigital.com/nfe.aspx

[]'s

Marcelo Rocha

On Apr 24, 12:54 pm, Hu Chia Fo <h...@ig.com.br> wrote:
> Obrigado Roberto pela dica.
> O problema é que a empresa já adquiriu o certificado em Smart Card !
> Vou continuar tentando e se encontrar solução , posto no grupo.
>
> Abraço
> Hu
>
> 2009/4/24 Roberto L. Machado <roberto.mach...@superig.com.br>
>
>
>
> > Pessoal;
>
> > Evitem o uso de certificados digitais no padrão A3 (validade de 3 anos e
> > vem no smart card ou em um token)
>
> > Prefiram o certificado A1 (validade de 1 ano e vem em arquivo eletrônico)
>
> > Acessar o smartcard ou o token nem sempre é tarefa fácil (no linux por
> > exemplo) e sempre é mais lento que acessar o certificado diretamente.
>
> > Se usar o A1, compre dois certificados com intervalo entre as compras de
> > aproximadamente  6 a 9 meses e monte uma rotina para controlar a validade
> > dos mesmos, esta solução sai mais caro (cerca de R$ 500,00 por ano) mas em
> > termos de flexibilidade é muito melhor.
>
> > []'s- Hide quoted text -
>
> - Show quoted text -

Marcelot

unread,
Jun 24, 2009, 1:58:42 PM6/24/09
to PHP Avançado
não acho que uma solução em Delphi e C# pode ser usada assim, sem
autorização, alem do mais acho melhor tentar mais um pouco com php

uma consideração importante para instalarção das ferramentas para
assinara a nota:
o Sr. Roberto L. Machado disponibilizou o seguinte material:
http://wiki.gophp.com.br/index.php?title=Assinar_NFe
que esta sendo de grande ajuda, pecebi que para usar o exemplo se faz
necessário instalar o seguintes itens (no Debian):
instalar XMLlib
instalar libxml2-dev
instalar libxslt-dev
cryptonit
libcrypt-openssl-x509-perl
libcurl4-openssl-dev
curl
sudo apt-get install curl libcurl3 libcurl3-dev php5-curl
/etc/init.d/apache2 restart
apt-get install xmlsec1

gerar um .pem:
openssl pkcs12 -in /var/www/nfe/testelocal/xxx.pfx -out /var/www/nfe/
testelocal/yyy.pem

gunzip -c xmlsec1-xxx.tar.gz | tar xvf -
cd xmlsec1-xxxx
./configure --help
./configure [possible options]
make
make install
make check
http://www.aleksey.com/xmlsec/download.html

além é claro o PHP 5


On 15 jun, 16:46, Marcelo Rocha <marcelo....@gmail.com> wrote:
> Pessoal, se vocês quiserem (por questão de prazo por exemplo) apenas
> gerar o XML da NFe, tenho uma boa notícia para vocês:
>
> RDI anuncia Open NFe
> Solução de Código Aberto para Nota Fiscal Eletrônica
>
> Belo Horizonte (12/06/2009) - Com o objetivo de auxiliar as empresas
> desenvolvedoras de softwares, a RDI disponibiliza a partir de hoje,
> além dos binários, também o código-fonte de seu Servidor de Nota
> Fiscal Eletrônica. O antigo NFe Admin 2009 agora passa a se chamar
> Open NFe. A idéia é oferecer aos desenvolvedores uma solução de código
> aberto (Open Source) que cuide da assinatura, envio e tratamento de
> contigência das Notas Fiscais Eletrônicas, além da impressão de DANFE.
> O trabalho do desenvolvedor fica restrito a gerar o XML de acordo com
> as especificações da Secretaria da Fazenda para o SPED (Sistema
> Público de Escrituração Digital). O Open NFe é distribuído sob a
> licença GPL.
> Mais informações emhttp://www.rochadigital.com/nfe.aspx

Marcelot

unread,
Jun 24, 2009, 2:38:54 PM6/24/09
to PHP Avançado
Olá.
gostaria de uma ajuda do Sr. Roberto L. Machado:
no exemplo de assinatura disponibilizado cordialmente em
http://wiki.gophp.com.br/index.php?title=Assinar_NFe
o que significa ou como obtenho os dados para estas viariaveis:

$keyName = 'privkey.pem';
$certName = 'mycert.pem';
pois até agora so uso este comando: (que converte um pfx para pem)
openssl pkcs12 -in /var/www/nfe/testelocal/xxx.pfx -out /var/www/nfe/
testelocal/yyy.pem

Muito obrigado
>     make checkhttp://www.aleksey.com/xmlsec/download.html

Marcelo Telles

unread,
Jun 24, 2009, 2:41:23 PM6/24/09
to PHP Avançado
seria isso:

#> opensl pkcs12 -in certificado.pfx -out ca.pem -cacerts -nokeys

//extrair o certificado do cliente

#>openssl pkcs12 -in certificado.pfx -out cliente.pem -clcerts -nokeys

//extrair a chave privada



2009/6/24 Marcelot <marcelo...@gmail.com>



--
Marcelo Josué Telles
Professor Escola Olímpio
Desenvolvimento Login Sat
Msn: marce...@msn.com
Fone: 51 3595 2362
Cel: 51 9164 0596


Daniel Batista Lemes

unread,
Jun 24, 2009, 2:53:26 PM6/24/09
to phpav...@googlegroups.com
Se tiver acesso ao shell do linux da pra assinar  só com comandos do shell, utilizando exec do php

2009/6/24 Marcelo Telles <marcelo...@gmail.com>

Walber S Sales

unread,
Jun 24, 2009, 3:02:56 PM6/24/09
to phpav...@googlegroups.com
Esta pegando na assinatura apenas para finalizar tudo em PHP.
 
Outro detalhe é no SCHEMA com unidade com apenas 2 letras
Se lanço UNIDAD da certo, se lanço UN não da certo.
 
 
Para ver basta alterar o texto de UNIDAD para UN e clikar em gerar xml.
 
[]'s
 
Walber Sales

Marcelo Telles

unread,
Jun 24, 2009, 3:03:39 PM6/24/09
to PHP Avançado
corrigindo:



//extrair o certificado do cliente

#>openssl pkcs12 -in certificado.pfx -out cliente.pem -clcerts -nokeys

//extrair a chave privada

#>openssl pkcs12 -in certifciado.pfx -out privkey.pem -nocerts



2009/6/24 Marcelo Telles <marcelo...@gmail.com>

Roberto L. MAchado

unread,
Jun 24, 2009, 6:09:12 PM6/24/09
to phpav...@googlegroups.com
Se voce for usar o php para assinar use a xmlseclibs.php (http://code.google.com/p/xmlseclibs/source/browse/trunk/xmlseclibs.php?spec=svn12&r=12)

Certificado Digital

Quando é adquirido o certificado digital, modelo A1, é fornecido no formato pfx (que é o mesmo que pkcs12) para usa-lo no PHP é necessário converter para o formato pem. Para isso temos que ter instalado o openssl e usar os comandos :

//extrair os certificados da cadeida de certificação apenas


#> opensl pkcs12 -in certificado.pfx -out ca.pem -cacerts -nokeys

//extrair o certificado do cliente

#>openssl pkcs12 -in certificado.pfx -out cliente.pem -clcerts -nokeys

//extrair a chave privada

#>openssl pkcs12 -in certifciado.pfx -out privkey.pem -nocerts

Estas conversões irão solicitar a "senha" que foi usada na criação do certificado e uma "palavra-chave" para encriptar a chave privada.

Caso não queira encriptar a chave privada utilize :

#>openssl pkcs12 -in certificado.pfx -out privkey.pem -nocerts -nodes

Neste caso não será solicitada a "palavra-chave" de encriptação.

 
[]
Roberto

Marcelo Telles

unread,
Jun 24, 2009, 7:56:25 PM6/24/09
to phpav...@googlegroups.com
Fiz mais alguns teste e funcionou perfeitamente, MUITO obrigado Roberto, seu material foi de grande ajuda, abaixo coloco seu material novamente com comentários que pode ajudar programadores menos experientes como no meu caso:
<?
/**
 * Código postado por Roberto L. Machado - linux.rlm [PHP Avançado]
 *    http://groups.google.com.br/group/phpavancado/
 *
 *    This program is free software; you can redistribute it and/or

 *    modify it under the terms of the GNU General Public License

 *    as published by the Free Software Foundation; either version 2

 *    of the License, or (at your option) any later version.

 *

 *    This program is distributed in the hope that it will be useful,

 *    but WITHOUT ANY WARRANTY; without even the implied warranty of

 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *    GNU General Public License for more details.

 *    http://www.gnu.org/licenses/gpl.txt
 *
 */

    $nfeDir = 'inNF/'; //diretorio onde sera gravado o xml assinado
    $nfeName = 'nfe.xml';// nome qeu sera dado ao arquivo xml assinado
   
    $filename = $nfeDir.$nfeName;     // diretorio e nome do arquivo xml da nota fiscal  ser assinado   
    $res = sign($filename); // efetuar a assinatura

    //mostra o documento assinado em tela
        $nfe = file_get_contents($res);
    header('Content-type: text/xml');
    PRINT  $nfe;

function sign($filename){

    $xmldoc = new DOMDocument(); //inicia objeto DOM
    $xmldoc->preservWhiteSpace = FALSE; //elimina espaços em branco
    $xmldoc->load($filename); //carrega o xml no objeto

    $infNFe = $xmldoc->getElementsByTagName('infNFe')->item(0); //cria um objeto DOM com o conteudo do node infNFe
    $id = trim($infNFe->getAttribute("Id")); //extrai o id da NF, será necessário adiante no node da assinatura
    unset($infNFe); // limpa a variável

    /*************************************
    * Para que o XMLSEC possa assinar o documento é necessário criar o
    * tamplate da assinatura no XML
    **************************************/
    $NFe = $xmldoc->getElementsByTagName('NFe')->item(0); //carrega o node raiz NFe
    $Signature = $xmldoc->createElement ('Signature'); //cria o nove da assinatura digital
    $Signature->setAttribute("xmlns", "http://www.w3.org/2000/09/xmldsig#"); //estabelece o formato da assinatura
    $NFe->appendChild($Signature); //acrescenta o node ao objeto XML

    $SignedInfo = $xmldoc->createElement('SignedInfo'); // cria a tag SignedInfo
    $Signature->appendChild($SignedInfo); //acrescenta a tag ao node Signature

    $SignatureValue = $xmldoc->createElement('SignatureValue'); // cria a tag SignatureValue
    $Signature->appendChild($SignatureValue); //acrescenta a tag ao node Signature

    $KeyInfo = $xmldoc->createElement('KeyInfo'); // cria a tag KeyInfo
    $Signature->appendChild($KeyInfo); //acrescenta a tag ao node Signature

    $X509Data = $xmldoc->createElement('X509Data'); // cria a tag X509Data
    $KeyInfo->appendChild($X509Data); //acrescenta a tag ao node KeyInfo
           
    $X509Certificate= $xmldoc->createElement('X509Certificate'); // cria a tag X509Certificate
    $X509Data->appendChild($X509Certificate); //acrescenta a tag ao node X509Data       

    $CanonicalizationMethod = $xmldoc->createElement('CanonicalizationMethod'); // cria a tag CanonicalizationMethod e seu atributo 
    $CanonicalizationMethod->setAttribute("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
    $SignedInfo->appendChild($CanonicalizationMethod); //acrescenta a tag ao node SignedInfo       

    $SignatureMethod  = $xmldoc->createElement( 'SignatureMethod' ); // cria a tag SignatureMethod e seu atributo
    $SignatureMethod->setAttribute('Algorithm', 'http://www.w3.org/2000/09/xmldsig#rsa-sha1' );
    $SignedInfo->appendChild($SignatureMethod ); //acrescenta a tag ao node SignedInfo       

    $Reference = $xmldoc->createElement( 'Reference' ); // cria a tag Reference
    $Reference->setAttribute("URI", '#'.$id); // acrescenta o atributo com o id da NFe obitido anteriormente
    $SignedInfo->appendChild($Reference ); //acrescenta a tag ao node SignedInfo       

    $Transforms = $xmldoc->createElement('Transforms'); // cria a tag Transforms
    $Reference -> appendChild($Transforms); //acrescenta a tag ao node Reference
   
    $Transform = $xmldoc->createElement('Transform'); // cria a tag Transform e seu atributo
    $Transform  -> setAttribute('Algorithm', 'http://www.w3.org/2000/09/xmldsig#enveloped-signature' );
    $Transforms-> appendChild($Transform); //acrescenta a tag ao node Transforms

    $Transform = $xmldoc->createElement('Transform'); //acrescenta outra tag Transform e seu atributo
    $Transform  -> setAttribute('Algorithm', 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315' );
    $Transforms-> appendChild($Transform); //acrescenta a tag ao node Transforms

    $DigestMethod  = $xmldoc->createElement('DigestMethod'); // cria a tab DigestMethod e seu atributo
    $DigestMethod->setAttribute('Algorithm', 'http://www.w3.org/2000/09/xmldsig#sha1' );
    $Reference->appendChild($DigestMethod ); //acrescenta a tag ao node Reference
   
    $DigestValue = $xmldoc->createElement('DigestValue'); // cria a tab DigestValue
    $Reference->appendChild($DigestValue); //acrescenta a tag ao node Reference
   
    $xmldoc->saveXML(); // atualiza o objeto DOM com os novos nodes   

    /**************************************************
    * Fim da criação do template
    <Nfe xmlns="http://www.portalfiscal.inf.br/nfe">
        <infNFe versao="1.07" Id="NFe43060992665611012850550079000000011485651995">
            ...
            ...
        </infNFe>
        <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="#NFe43060992665611012850550079000000011485651995">
                    <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/>
                </Reference>
            </SignedInfo>
            <SignatureValue/>
            <KeyInfo>
                <X509Data>
                    <X509Certificate/>
                </X509Data>
            </KeyInfo>
        </Signature>
    </NFe>
    ***************************************************/

    // obter um nome para o arquivo temporário de entrada
    //$tmpfName = tempnam('./' , 'in'); tive que comentar esta linha e criar um nome para o arquivo com a extensão XML
    $tmpfName = './in/nfe.xml';

    // obter um nome para o arquivo temporário de saída
    //$outputName = tempnam('./' , 'outNF'); tive que comentar esta linha e criar um mome para o arquivo com a extensão XML
    $outputName = './outNF/notinha.xml';
   
    // salvar o XML alterado no arquivo temporário
    $xmldoc->save($outputDir.$tmpfName);
    // liberar da memória o objeto DOM
    unset($xmldoc);

    // arquivo certificado de usuário possui ambas as chaves (privada e publica) 
    $usercert12 = './NFE.pfx'; //este é o caminho para o certificado que é disponibiliazado pelas Agencias certificadoras, o arquivo pfx

    // senha da chave privada
    $password = 'senhadocertificado';

    // arquivo do certificado digital da entidade emissora
    $cacertpem = './NFE.pem'; //este é o arquivo do certificado digital devidamente convertido, isso pode ser feito pelo Debian ou MacOS pelo seguinte comando openssl pcks12 -in certificado.pfx -out NFE.pem
   
    /*********************************************************
    * Montar o comando shell para assinar o documento salvo no arquivo temporário
    * xmlsec1 - nome do comando no linux (para windows deve ser xmlsec.exe)
    * sign - solicitação de assinatura
    * --id-attr:Id infNFe - indica o que deve ser assinado apenas o node infNFe com o Id indicado pelo node Reference
    * --output <file> - indica o arquivo de saida do comando ou seja o XML assinado
    * --pkcs12 <private-key> - indica o arquivo do certificado do usuário no formato pkcs12
    * --pwd <password> - indica a senha da chave privada
    * --trusted-pem <certificate> - indica o arquivo do certificado digital no formato pem
    * <inputfile> - no final o arquivo XML com o template da assinatura
    *************************************************************/
    $cmd = "xmlsec1 sign --id-attr:Id infNFe --output $outputName --pkcs12 $usercert12 --pwd $password --trusted-pem $cacertpem $tmpfName 2>&1";
    //executa o comando na shell e retorna o resultado em $read
    $p = popen( $cmd, 'r');
    $read = fread($p , 4096);
    pclose($p);

    //apaga o arquivo temporário e limpa a memória   
    $z = unlink($tmpfName);
    unset($tmpfName);   
   
    // remove quaisquer LF ou CR que ainda estejam no documento - vide Manual de Integração
    $outDocument = file_get_contents($outputName);
    $outDocument = str_replace(chr(13),"",$outDocument);
    $outDocument = str_replace(chr(10),"",$outDocument);
    file_put_contents($outputName, $outDocument);

    // salva o XML como NFe43060992665611012850550079000000011485651995.xml   
    $signdoc = new DOMDocument();
    $signdoc->preservWhiteSpace = FALSE;
    $signdoc->load($outputName);
    $signdoc->saveXML();
    $xmlName = $id.'.xml';   
    $signdoc->save($xmlName);
    // limpa a memoria e apaga o documento temporário
    unset($signdoc);   
    $z = unlink($outputName);   
    unset($outputName);   

    // retorna o nome do arquivo assinado
    return $xmlName;
}

?>



2009/6/24 Roberto L. MAchado <roberto...@superig.com.br>

Walber S Sales

unread,
Jun 24, 2009, 11:47:01 PM6/24/09
to phpav...@googlegroups.com
gALLera,
 
Fiz uns testes, usando como localhost o XP/APACHE/PHP/
Consegui chegar neste XML.
 
..
..
..
        </transp>
    </infNFe>
<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="#NFe31090664418601000100550000000000014587404731"><Transforms>
<DigestValue/></Reference></SignedInfo>
<SignatureValue/>
<KeyInfo><X509Data><X509Certificate/></X509Data></KeyInfo>
</Signature></NFe>
 
Quando vai executar a linha
 
$cmd = "xmlsec sign --id-attr:Id infNFe --output $outputName --pkcs12 $usercert12 --pwd $password --trusted-pem $cacertpem $tmpfName 2>&1";
 
Recebo esta mensagem:
 
'xmlsec' nÆo ‚ reconhecido como um comando interno ou externo, um programa oper vel ou um arquivo em lotes.
 
Procurei no HD por este arquivo xmlsec não achei, alguma luz?
 
Grato,
 
Walber Sales
 
PS: Sei que em listas como esta é até proibido vender algo mas dicas como este email anterior tem que valer $uce$$o para autor que disponibilzou.
 
 
 
 
 
----- Original Message -----

Walber S Sales

unread,
Jun 26, 2009, 1:06:46 AM6/26/09
to phpav...@googlegroups.com
Boa noite,
 
Depois de tentar com XMLSEC e nada,  tentei via xmlseclibs.php
e obtive isto.
 
Alguma luz?
 
Grato,
 
Walber Sales
 

Warning: openssl_sign() [function.openssl-sign]: supplied key param cannot be coerced into a private key in D:\wss\web\cadastros\includes\xmlseclibs\xmlseclibs.php on line 399

Fatal error: Uncaught exception 'Exception' with message 'Failure Signing Data' in D:\wss\web\cadastros\includes\xmlseclibs\xmlseclibs.php:400 Stack trace: #0 D:\wss\web\cadastros\includes\xmlseclibs\xmlseclibs.php(435): XMLSecurityKey->signOpenSSL('<ds:SignedInfo ...') #1 D:\wss\web\cadastros\includes\xmlseclibs\xmlseclibs.php(1018): XMLSecurityKey->signData('<ds:SignedInfo ...') #2 D:\wss\web\cadastros\includes\xmlseclibs\xmlseclibs.php(1031): XMLSecurityDSig->signData(Object(XMLSecurityKey), '<ds:SignedInfo ...') #3 D:\wss\web\cadastros\includes\nfe_sign_nfe2.php(51): XMLSecurityDSig->sign(Object(XMLSecurityKey)) #4 {main} thrown in D:\wss\web\cadastros\includes\xmlseclibs\xmlseclibs.php on line 400

Walber S Sales

unread,
Jun 26, 2009, 1:26:09 AM6/26/09
to phpav...@googlegroups.com
Help,
 
Já extrai de 3 maneiras diferentes os PEM do certificado PFX.
Qual devo usar para assinar.
 
01)
# openssl pkcs12 -nodes -in cert.pfx  -out cert.pem
 
02)
//extrair o certificado do cliente
#>openssl pkcs12 -in certificado.pfx -out cliente.pem -clcerts -nokeys
 
03)
//extrair a chave privada
#>openssl pkcs12 -in certifciado.pfx -out privkey.pem -nocerts
 
 
Agradeço,
 
Walber Sales

Marcelo Telles

unread,
Jun 26, 2009, 7:20:58 AM6/26/09
to phpav...@googlegroups.com
confira a correta forma de extrair: (no linux Ubuntu 8,10 Debian 2.26 e Mac OS 10.x, sei que funciona.)
openssl pkcs12 -in NFe_Cliente_tal.pfx -out NFE.pem -clcerts -nokeys
Dai pede a senha do certificado.

e nao esqueça que com xmlseclibs vc precisa entregar o caminho completo do arquivo original o tal .pfx e o convertido, o tal do .pem, olhe o trecho que isso é feito:

$cacertpem = './NFE.pem'; //este é o arquivo do certificado digital devidamente convertido, isso pode ser feito pelo Debian ou MacOS pelo seguinte comando openssl pcks12 -in certificado.pfx -out NFE.pem -clcerts -nokeys 
   

$usercert12 = './NFE.pfx'; //este é o caminho para o certificado que é disponibiliazado pelas Agencias certificadoras, o arquivo pfx

Outra dica é vc interpretar corretamente o comando que o Sr. Roberto nos passou, tente fazer com que este comando funcione teste ele pela linha de comando:

$cmd = "xmlsec1 sign --id-attr:Id infNFe --output $outputName --pkcs12 $usercert12 --pwd $password --trusted-pem $cacertpem $tmpfName 2>&1";
   
veja os detalhes que ele nos passou:

/*********************************************************
    * Montar o comando shell para assinar o documento salvo no arquivo temporário
    * xmlsec1 - nome do comando no linux (para windows deve ser xmlsec.exe)
    * sign - solicitação de assinatura
    * --id-attr:Id infNFe - indica o que deve ser assinado apenas o node infNFe com o Id indicado pelo node Reference
    * --output <file> - indica o arquivo de saida do comando ou seja o XML assinado
    * --pkcs12 <private-key> - indica o arquivo do certificado do usuário no formato pkcs12
    * --pwd <password> - indica a senha da chave privada
    * --trusted-pem <certificate> - indica o arquivo do certificado digital no formato pem
    * <inputfile> - no final o arquivo XML com o template da assinatura
    *************************************************************/
   
Boa sorte.


2009/6/26 Walber S Sales <onl...@multnet.com.br>

Roberto L. MAchado

unread,
Jun 26, 2009, 7:40:04 AM6/26/09
to phpav...@googlegroups.com
Walber;

Tenho uma API em fase de desenvolvimento se quiser participar eu incluo voçê ...

O que a API já faz :

Assina NFe (em xml) //totalmente funcional e simples
E executa alguns serviços na SEFAZ (estou concluindo os outros serviços)

Esta minha classe esta disponibilizada no Assembla sob o none NFePHP

Interessa ?

Roberto

Walber S Sales

unread,
Jun 26, 2009, 2:10:57 PM6/26/09
to phpav...@googlegroups.com
Opa! ' Tô dentro '.
Interesso sim.
 
[]'s
 
Walber
 
 
----- Original Message -----

Walber S Sales

unread,
Jun 26, 2009, 5:41:50 PM6/26/09
to phpav...@googlegroups.com
Roberto,  faço login no assembla e nào consigo localizar o arquivo.
Qual é seu contato (tel, msn)?
Favor enviar para onl...@multnet.com.br
 
Grato,
 
Walber Sales
 
----- Original Message -----
Sent: Friday, June 26, 2009 8:40 AM
Subject: [Php Avançado: 1218] Re: Assinatura Digital NF-e

Roberto L. MAchado

unread,
Jun 27, 2009, 3:34:48 PM6/27/09
to phpav...@googlegroups.com
Walber;

Cel:  (11) 8338-9290
MSN : roberto...@superig.com.br
skype : robmachado5160

[]'s

Roberto L. MAchado

unread,
Jun 27, 2009, 5:47:01 PM6/27/09
to phpav...@googlegroups.com
Procure usando o mecanismo de busca do assembla com "nfe" somente ai vai aparecer NFePHP

ai é só clicar no link

[]
Roberto

Walber S Sales

unread,
Jun 27, 2009, 9:50:23 PM6/27/09
to phpav...@googlegroups.com
Consegui achar NFePHP , apenas não acho nada para download.
Qual aba?
 
Att:
 
Walber

Walber S Sales

unread,
Jun 27, 2009, 10:18:16 PM6/27/09
to phpav...@googlegroups.com
Boa Noite,
 
Ao adquirirmos o certificado digitaldo tipo A1 ele é extraido no formato .pfx
Estou notando que  para a NFe  na hora de  transmitir ou assinar em PHP temos que tranformar em .pem
Minha dúvida é a seguinte.
Porque alguns outros utilitários, como o www.uninfe.com.br  ao assinar o xml ele não precisa transformar para .pem, apenas reconhece o original .pfx?
 
Grato,
 
Walber Sales
 
 
 
 
----- Original Message -----

Walber S Sales

unread,
Jun 27, 2009, 10:48:33 PM6/27/09
to phpav...@googlegroups.com
Boa noite,
 
 
O que deve estar acontecendo:
Usando xmlseclibs.php para assinar, recebo esta mensagem:  (WINDOWS)

Warning: openssl_sign() [function.openssl-sign]: supplied key param cannot be coerced into a private key in D:\wss\web\cadastros\nfe\xmlseclibs.php on line 402
 
 

Coloco a senha e os certificados da maneira abaixo
 

$keyName = 'privekey3_core.pem';
$keyPass = 'XXXX';
$certName = 'ca2_core.pem';

Roberto L. MAchado

unread,
Jun 28, 2009, 8:11:05 AM6/28/09
to phpav...@googlegroups.com
Procure a ABA sources/svn

É preferivel usar o subversion para baixar os arquivos

Roberto

Roberto L. MAchado

unread,
Jun 28, 2009, 8:13:33 AM6/28/09
to phpav...@googlegroups.com
Os aplicativos linux (exceto o java) não trabalham bem com o pfx visto que um formato windows

este formato é equivalente ao pkcs12 que agrupa em um unico arquivo os varios certificados e chaves

Roberto

Roberto L. MAchado

unread,
Jun 28, 2009, 8:15:04 AM6/28/09
to phpav...@googlegroups.com
É provavel que haja um problema no arquivo extraido do arquivo original qual o comando que voce utilizou para extrair a chave privada ?

Roberto

Walber S Sales

unread,
Jun 28, 2009, 8:48:23 AM6/28/09
to phpav...@googlegroups.com
Quando trabalho com SOAP em webservice, uso assim:
$certFile = 'd:\wss\web\nfe\certificado_wea.pem';
$pass     = 'pass';
E $certfile foi extraido desta maneira:

# openssl pkcs12 -nodes -in certificado_wea.pfx  -out certificado_wea.pem
 
 
 
      Agora para assinar são tantas extrações que esta me confundindo:
Retirei do exemplo seu em ASSEMBLA NFePHP.
 
//extrair os certificados da cadeida de certificação apenas
opensl pkcs12 -in certificado.pfx -out ca.pem -cacerts -nokeys
 
//extrair o certificado do cliente
openssl pkcs12 -in certificado.pfx -out cliente.pem -clcerts -nokeys
 
//extrair a chave privada
openssl pkcs12 -in certifciado.pfx -out privkey.pem -nocerts
 
São tantos que não sei nem qual usuar mais.  (rsrs)
 
Qual é o $usercert12 ?
Qual é o $cacertpem ?
Qual é o $keyName ?
Qual é o $certName?
 
$keyPass é a senha que vem fornecido com o certificado pela CA? Ou o literal que informamos depois da senha ao extrair a chave privada?
 
' Tô '  meio perdido com estes certificados, depois de extrair tem que instalar algo?
 
Grato,
 
Walber Sales
 
 
 
 
 

 
 
 
 
----- Original Message -----

Roberto L. MAchado

unread,
Jun 28, 2009, 9:06:07 AM6/28/09
to phpav...@googlegroups.com
Walber voce tem
skype: robmachado5160
ou
MSN: roberto...@superig.com.br


meu tel : (11) 5073-4858

Roberto

Roberto L. MAchado

unread,
Jun 28, 2009, 9:36:32 AM6/28/09
to phpav...@googlegroups.com
Extraia a chave privada
openssl pkcs12 -in certificado.pfx -out keyname.pem -nocerts -nodes

Extraia o certificado do cliente
openssl pkcs12 -in certificado.pfx -out certname.pem -clcerts -nokeys

É isso

Roberto

Walber S Sales

unread,
Jun 28, 2009, 10:08:19 PM6/28/09
to phpav...@googlegroups.com
Roberto, com grandes dicas suas  a assinatura foi feita , totalmente adicionada no XML.
E fui dar sequências.
 
Usando   new nusoap_client( $wsdl, 'WSDL' );
 
 
Consigo enviar o XML e receber retorno de envio com sucesso.
 <xMotivo>Lote recebido com sucesso</xMotivo>
Quando consulto o retorno da autorização , a mensagem foi.
<xMotivo>Rejeicao: Falha no Schema XML da NFe</xMotivo>
 
Tira-teima:
 
O mesmo XML gerado, peço para assinar e enviar por outro aplicativo.
Faço uma nova consulta como a anterior.
O resultado.
<xMotivo>Autorizado o uso da NF-e</xMotivo>
 
 
Comparei os 2 XML na assinatura.
 
 
O assinado pelo PHP

<DigestValue>/aE432+F9lTkYzM4qiNYgpb7htI=</DigestValue></Reference></SignedInfo>
<SignatureValue>BOpILKTc2R3/1zLWQ12y6RhH8paHSc1h0PIUP+uYe7RPEFkSh+PvA
L21niVVjjOzyrb9a4dyfpSz....................................
 
 
O assinado pelo outro aplicativo.
 
<DigestValue>mtOkl/zrrkB1qonJU1PrSKNsVRo=</DigestValue></Reference></SignedInfo>
<SignatureValue>pCs1JqA1nuJ+35+tqsppQpLh9RYSqO1IONJJ5E3+aebcjnm6JJ1LftrHBjpu
TaLBT0eYegmL.....................................................
 
 
O assinado pelo ASSINADOR RS foi igual ao UNINFE
 
DigestValue>mtOkl/zrrkB1qonJU1PrSKNsVRo=</DigestValue></Reference></SignedInfo>
<SignatureValue>pCs1JqA1nuJ+35+tqsppQpLh9RYSqO1IONJJ5E3+aebcjnm6JJ1LftrHBjpu
 
 
Vou fazer mais testes para ver se consigo igualar as assinaturas.
Se conseguir,vai ser mais um passo.
' Eita '  NFe cheia de passos.

Marcelo Telles

unread,
Jun 29, 2009, 8:20:50 AM6/29/09
to phpav...@googlegroups.com
mas Walber, precisa ficar igual?

2009/6/28 Walber S Sales <onl...@multnet.com.br>



--
Marcelo Josué Telles
Professor Escola Técnica Olímpio

Desenvolvimento Login Sat
Msn: marce...@msn.com
Fone: 51 3595 2362
Cel: 51 9164 0596
Linux user 492525


Daniel Lemes

unread,
Jun 29, 2009, 8:22:33 AM6/29/09
to phpav...@googlegroups.com
Claro, se for o mesmo certificado do mesmo XML tem que ser a mesma assinatura, por isso assinatura.
----- Original Message -----

Raphael Canguçu

unread,
Jun 28, 2009, 9:47:17 PM6/28/09
to phpav...@googlegroups.com
Prezados,

Onde posso baixar o código dessa API? Tem algum SVN, CVS ou SourceSafe?

Att.

2009/6/28 Roberto L. MAchado <roberto...@superig.com.br>



--
Raphael Canguçu
(31) 8432-6486 / 3303-1275
rap...@codificar.com.br
skype: raphaelcmf
http://www.codificar.com.br
http://www.noticiaria.com.br

Reinaldo Borges

unread,
Jun 25, 2009, 10:59:35 AM6/25/09
to PHP Avançado
Bom dia,

A chave privada presente em smart card e token não pode ser exportada.
Essa é a razão de existir smart card
e token: não ser possível usar a chave sem o próprio cartão ou token.

Nunca usei PHP com certificado A3. Talvez seja melhor usar o shell
(exec, system, passthru) para
chamar o OpenSSL. Sei que o OpenSSL pode solicitar a assinatura de
arquivos usando certificados
A3.

Acho que a saída será por esse caminho.

Raphael Cangucu

unread,
Jun 27, 2009, 4:26:29 PM6/27/09
to PHP Avançado, Roberto L. MAchado
Prezados,

Tenho total interesse de participar do desenvolvimento dessa API.
Acredito que posso contribuir de maneira positiva nesse projeto.

Meus dados são:

MSN e GTALK: rap...@codificar.com.br
Skype: raphaelcmf

Atenciosamente.

On 27 jun, 16:34, "Roberto L. MAchado"
> ...
>
> mais »

Walber S Sales

unread,
Jun 29, 2009, 1:14:32 PM6/29/09
to phpav...@googlegroups.com
Olá Roberto,
 
Adicionei vc no MSN e SKYPE
Te liguei no seu tel....
A TAG <X509Certificate>  esta repetindo 4 vezes na sua assinatura?
 
 
[]'s

Walber S Sales

unread,
Jun 29, 2009, 1:16:09 PM6/29/09
to phpav...@googlegroups.com
Marcelo,  gerei com 3 aplicativos diferentes e os 2 que aceitaram (Retorno OK)  eram iguais.
Então deduzo que em termos de assinatura, sendo os XML iguais, elas também devem ser iguais.
[]'s

Roberto L. MAchado

unread,
Jun 29, 2009, 5:18:06 PM6/29/09
to phpav...@googlegroups.com
Raphael;

Já enviei convites para você varias vezes, e não houve retorno.

Procure no Assembla (search nfe )

Roberto

Em Dom, 2009-06-28 às 22:47 -0300, Raphael Canguçu escreveu:
rap...@codificar.com.br>

Raphael Canguçu

unread,
Jun 29, 2009, 5:57:38 PM6/29/09
to phpav...@googlegroups.com
Roberto,

Fiz isso e já estou no grupo.

Devo iniciar as atividades nesse projeto a partir de semana que vem.

Att.

2009/6/29 Roberto L. MAchado <roberto...@superig.com.br>

Marcelo Telles

unread,
Jul 1, 2009, 8:51:39 AM7/1/09
to phpav...@googlegroups.com, Roberto L. MAchado
Sr. Roberto é possível disponibilizar um arquivo texto de exemplo no seu Layout para conversão para XML?
Grato

2009/6/27 Raphael Cangucu <rap...@codificar.com.br>



--
Marcelo Josué Telles
Professor Escola Técnica Olímpio

Desenvolvimento Login Sat
Msn: marce...@msn.com
Fone: 51 3595 2362
Cel: 51 9164 0596
Linux user 492525


Walber S Sales

unread,
Jul 3, 2009, 9:38:50 AM7/3/09
to phpav...@googlegroups.com
Vejam a parte do XML enviado, é tpAmb=2
 
 
  <cUF>31</cUF>
  <cNF>465080646</cNF>
  <natOp>VENDAS DE MERCADORIAS</natOp>
  <indPag>2</indPag>
  <mod>55</mod>
  <serie>0</serie>
  <nNF>10</nNF>
  <dEmi>2009-07-03</dEmi>
  <dSaiEnt>2009-07-03</dSaiEnt>
  <tpNF>1</tpNF>
  <cMunFG>3134202</cMunFG>
  <tpImp>1</tpImp>
  <tpEmis>1</tpEmis>
  <cDV>6</cDV>
  <tpAmb>2</tpAmb>
  <finNFe>1</finNFe>
  <procEmi>0</procEmi>
  <verProc>1.0</verProc>
 
 
O retorno é:
tMed=3
dhRecbto=2009-07-03T10:27:18
nRec=310000014551171
cStat=103
Amb=1
verAplic=
Motivo=Lote recebido com sucesso
cUF=31
 
E quando consulto a resposta, vejam o resultado.
 
<tpAmb>1</tpAmb>
 <verAplic>1.10</verAplic>
  <nRec>310000003489619</nRec>
  <cStat>252</cStat>
  <xMotivo>Rejeicao: Ambiente informado diverge do Ambiente de recebimento</xMotivo>
  <cUF>31</cUF>
 
 
Alguém passou por esta?
 
Grato,
 
Walber Sales

Vinicius Lacerda

unread,
Jul 3, 2009, 10:17:48 AM7/3/09
to phpav...@googlegroups.com
Acho que quando a nota foi enviada, ela foi com tpAmb '1' que é produção.

2009/7/3 Walber S Sales <onl...@multnet.com.br>

Jean

unread,
Jul 3, 2009, 10:35:19 AM7/3/09
to phpav...@googlegroups.com
Bom dia Walber,

Verifique as URLs dos serviços solicitados e também o tipo de ambiente informado nos XMLs, ja passei uma vez por isso, e o meu caso meu XML estava apontando para o ambiente de homologação enquanto minha URL estava apontando para o ambiente de produção.

2009/7/3 Vinicius Lacerda <vlac...@gmail.com>



--
Jean Dias
Time Informática LTDA
Blumenau - SC
(47) 3041-9009

Walber S Sales

unread,
Jul 5, 2009, 1:03:53 AM7/5/09
to phpav...@googlegroups.com
Boa noite Roberto,
 
 
Baixei as novas alterações e comecei a testar.
Primeiramente estou tentando via autosign para assinar.
Fui ajustando até chegar neste ponto que não consigo passar na classe classNFe.php
 
$resp = openssl_sign($dados,$signature,$rPrivkey);
 
 
Warning: openssl_sign() [function.openssl-sign]: supplied key param cannot be coerced into a private key in D:\wss\web\assembla\nfephp\libs\classNFE.php on line 273
 
Quando faço um echo antes de $resp veja o que tem.
 
              echo $dados.'(1) '.$signature.' (2) '.$rPrivkey;
 
+dtzOfu0PUJvfZgiiCpNuCtShwE=(1) (2)
 
Isto é,  $signature e $rPrivkey veio vazio, não deve ser normal né?
 
Alguma dica?
 
Também notei que você acrescentou um novo certificado em config_inc, o $certp12.
Este é o .pfx?
 
Grato,
 
 
Walber Sales
 
 
 
 

Roberto L. MAchado

unread,
Jul 5, 2009, 8:29:44 AM7/5/09
to phpav...@googlegroups.com
Walber;

Para usar o assinador em PHP ou com xmlsec1 é necessario apontar no config_inc.php o caminho para o certificado original (certificado.pfx) só um detalhe renomear o certificado com a terminação ".p12" .

Se você olhar o codigo vera que $rPrivKey é um resource onde foi carregada a chave a partir do certificado pfx. (Nota: $rPrivKey não é uma string OK!!!)

Esse codigo funciona perfeitamente no meu ambiente (Linux) porém eu não testei sob windows.

A informação que você esta recebendo é um "Aviso apenas" pois foi gerada a assinatura, evite verificar o conteudo de $signature pois é uma string com codigos de controle também o valor correto esta em $signatureValue que é o mesmo valor original codificado em base64.

Os "Avisos" pode ser desabilitados no php e só deixar as mensagens de "Erro".

Aparentemente o assinador esta Normal sim...

Se voce não usa eu recomento fortemente que baixe o Netbeans e configure o Xdebug para construir e depurar os codigos.. é de gratis!! e ajuda um caminhão  ;-)

[]'s

Roberto

Walber S Sales

unread,
Jul 5, 2009, 10:57:31 PM7/5/09
to phpav...@googlegroups.com
Roberto, com a dica do rename p/ p.12  dei conta de dar sequência.
Postando aqui a conclusão.
 
Com códigos anteriores a atualização no assembla.
 
ANTES:
 
<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="#NFe31090764418601000100550000000000124650806460">
- <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>+dtzOfu0PUJvfZgiiCpNuCtShwE=</DigestValue>
  </Reference>
  </SignedInfo>
  <SignatureValue>dTvIe4XluJmy/UTaqo0DU6YfP277wna+Hr1RibLmZRP5ogTayN2gk84W6gC62Z7fQUwTR8p3vllArQ8e24vgQKzbzVxY+pwU2tIra6uJn/cXPLJiv7XQwOmbCB9AAFP0NEAzDLhUo08EXqNL5DsplMM7K/6iFgrdhqqSuYXe6iQ=</SignatureValue>
- <KeyInfo>
- <X509Data>
 
 
 
DEPOIS:
 

- <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
- <ds:SignedInfo>
  <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
  <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
- <ds:Reference URI="#NFe31090764418601000100550000000000124650806460">
- <ds:Transforms>
  <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
  <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
  </ds:Transforms>
  <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
  <ds:DigestValue>+dtzOfu0PUJvfZgiiCpNuCtShwE=</ds:DigestValue>
  </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>dTvIe4XluJmy/UTaqo0DU6YfP277wna+Hr1RibLmZRP5ogTayN2gk84W6gC62Z7fQUwTR8p3vllArQ8e24vgQKzbzVxY+pwU2tIra6uJn/cXPLJiv7XQwOmbCB9AAFP0NEAzDLhUo08EXqNL5DsplMM7K/6iFgrdhqqSuYXe6iQ=</ds:SignatureValue>
 
 
Conclusão:
 
As assinatura de antes e depois ficaram as mesmas, a diferença é que o DEPOIS apareceu os campos <ds:   que não existe no XML.
 
PS: Estou usando Windows, não testei com linux.
 
[]'s
 
Walber Sales
 
 
 
 
----- Original Message -----
Reply all
Reply to author
Forward
0 new messages