Pesquisar na Comunidade
Showing results for tags 'acbrdfewincrypt'.
Encontrado 2 registros
-
Assinatura de Documento Xml
um tópico no fórum postou Marcos Fernando Barbosa Dúvidas Gerais sobre o ACBr
Função para selecionar o certificado digital function SelCert: string; var Store: IStore3; CertsLista, CertsSelecionado: ICertificates2; CertDados: ICertificate; lSigner: TSigner; lSignedData: TSignedData; Cert: TCertificate; Ov: OleVariant; begin Result := ''; Store := CoStore.Create; try Store.Open(CAPICOM_CURRENT_USER_STORE, 'My', CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED); except On E: Exception do begin MsgErro(E.Message); Exit; end; end; try CertsLista := Store.Certificates as ICertificates2; CertsSelecionado := CertsLista.Select ('Certificado(s) Digital(is) disponível(is)', 'Selecione o Certificado Digital para uso no aplicativo', False); except On E: Exception do begin MsgErro('Operação cancelada pelo usuário!'); Exit; end; end; if not(CertsSelecionado.Count = 0) then begin CertDados := IInterface(CertsSelecionado.Item[1]) as ICertificate2; lSigner := TSigner.Create(nil); lSigner.Certificate := CertDados; lSignedData := TSignedData.Create(nil); lSignedData.Content := ' '; try lSignedData.Sign(lSigner.DefaultInterface, false, CAPICOM_ENCODE_BINARY); except On E : Exception do begin MsgErro('Erro na autenticação do Certificado Digital!'); Exit; end; end; Cert := TCertificate.Create(nil); Ov := IInterface(CertsSelecionado.Item[1]) as ICertificate2; Cert.ConnectTo(IDispatch(Ov) as ICertificate2); Result := Cert.Export(CAPICOM_ENCODE_BASE64); lSignedData.Free; lSigner.Free; end; Store.Close; end; function MontaFileAssinatura(const URI: String): String; var ArquivoXml: string; begin ArquivoXml := '<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="#' + URI + '">'+ '<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></DigestValue>' + '</Reference>' + '</SignedInfo>' + '<SignatureValue></SignatureValue>' + '<KeyInfo>' + '<X509Data>' + '<X509Certificate></X509Certificate>'+ '</X509Data>' + '</KeyInfo>' + '</Signature>'; Result := ArquivoXml; end; Com ou sem no da assinatura não esta funcionando function MontaFileXml(const FileXml, Id: string): string; begin Result := FileXml; // Result := StringReplace(FileXml, ':CERTIFICADO', MontaFileAssinatura(Id), [rfReplaceAll]); end; Função que deveria assinar o documento xml passado como parametro function Assinar(const FileXml, Id: string; var FileOut: string): Boolean; var A: TDFeSSL; B: TDFeSSLXmlSignXmlSec; C: TDFeWinCrypt; I: Integer; fileXmlNew, s : string; F : TStringList; begin fileXmlNew := MontaFileXml(FileXml, Id); Result := False; try try A := TDFeSSL.Create; A.SSLCryptLib := cryOpenSSL; A.SSLXmlSignLib := xsXmlSec; try C:= TDFeWinCrypt.Create(A); s := SelCert; if not Empty(s) then begin try if C.CarregarCertificadoPublico(AnsiString(s))then begin B:= TDFeSSLXmlSignXmlSec.Create(A); F := TStringList.Create; with F do begin Add(fileXmlNew); s := ''; for I := 0 to Count - 1 do S := S + Trim(StringReplace(StringReplace(Pchar(Strings[I]), #13, '', [rfReplaceAll]),#10,'',[rfReplaceAll])); Text := '<?xml version="1.0" encoding="iso-8859-1"?>' + B.Assinar(S,'Signature',''); FileOut := Text; end; end else begin MsgAdverte('Certificado digital selecionado inválido'); Exit; end; except On E1 : Exception do begin MsgErro('Erro durante a seleção do certificado ->' + sLineBreak + E1.Message); Exit; end; end; end else Exit; except On E2 : Exception do begin MsgErro('Erro ao carregar biblioteca do certificado digital ->' + sLineBreak + E2.Message); Exit; end; end; except On E3 : Exception do begin MsgErro('Erro ao carregar biblioteca dinâmica wincrypt do certificado digital ->' + sLineBreak + E3.Message); Exit; end; end; finally FreeAndNil(B); FreeAndNil(C); FreeAndNil(A); end; Result := True; end; Procedimento que passa o arquivo já formatado para realização da assinatura procedure TFormImportaXMLNFe.AdvGlowButton1Click(Sender: TObject); const xml: string = '<?xml version="1.0" encoding="UTF-8"?>'+ '<enviNFe versao="2.00" xmlns="http://www.portalfiscal.inf.br/nfe">' + '<idLote>71</idLote>' + '<NFe>' + '<infNFe id="NFe31120723401920000117550020000295121002311579" versao="2.00">' + '<cUF>35</cUF>' + '<cNF>518005127</cNF>' + '<natOp>Venda a vista</natOp>' + '<mod>55</mod>' + '<serie>1</serie>' + '<dEmi>2012-05-06</dEmi>' + '<tpAmb>2</tpAmb>' + '</infNFe>' + '</NFe>' + '</enviNFe>'; xml: string = '<?xml version="1.0" encoding="UTF-8"?>'+ '<enviNFe versao="2.00" xmlns="http://www.portalfiscal.inf.br/nfe">' + '<idLote>71</idLote>' + '<NFe>' + '<infNFe id="NFe31120723401920000117550020000295121002311579" versao="2.00">' + '<cUF>35</cUF>' + '<cNF>518005127</cNF>' + '<natOp>Venda a vista</natOp>' + '<mod>55</mod>' + '<serie>1</serie>' + '<dEmi>2012-05-06</dEmi>' + '<tpAmb>2</tpAmb>' + '</infNFe>' + ':CERTIFICADO' + '</NFe>' + '</enviNFe>'; var xmlAssi : string; begin inherited; if Assinar(xml,'NFe31120723401920000117550020000295121002311579', xmlAssi) then begin MsgAvisa('xml assinado: ' + sLineBreak + xmlAssi); end; end; Não completa o processo e sempre gera exceção, será que os desenvolvedores do componente não poderia criar um exemplo somente de uso dos componentes em questão já com o arquivo da nfe, cte, bpe para ser assinado.- 5 replies
-
- certificado
- segurança
- (e 8 mais)
-
acbrdfewincrypt Problemas com PIN A3 + Assinatura de XML
um tópico no fórum postou Data Lider ACBrNFe
Contextualizando Prezados, devido nossa aplicação ser em 3 camadas, a parte de assinatura do XML fica em uma aplicação externa em outra linguagem de programação, e no que diz respeito a parte de ENVIO basta mencionar o excelente trabalho que o projeto fez com a WinCrypt. obs: se você não sabe o porque de fazermos assim, segue o tópico EXCELENTE do Daniel O Problema Essa semana obtivemos um certificado A3 da Perto (SmartCard) e ele está pedindo PIN no servidor, e no DEBUG descobri que não era na nossa rotina de assinatura mas sim no momento do envio pela ACBr. A Causa Na unit "ACBrNFeNotasFiscais.pas", na linha 252, onde temos: TACBrNFe(TNotasFiscais(Collection).ACBrNFe).SSL.ValidarCNPJCertificado( NFe.Emit.CNPJCPF ); 1º Ele acaba inicializando todo contexto e enviando o PIN para o SmartCard (ou Token) previamente, antes da assinatura e antes do envio. 2º Quando o evento "OnAntesDeAssinar" é disparado nosso código externo realiza a assinatura do XML nessa biblioteca externa. 3º (Não tenho certeza) É provável que ao adquirir o contexto do certificado A3 nessa aplicação nossa, e enviar o PIN tem removido o contexto da ACBR ou algo semelhante, isso já vai um pouco além do que conheço do assunto. 4º Quando o código volta para a ACBR realizar o Envio, a janela de PIN aparece. 5º Quando debugando eu faço um Jump para a próxima linha pulando a linha 252 conforme destacada acima, tudo funciona normalmente, porque não houve um contexto anteriormente adquirido acima, então no momento do envio o código para obter a chave privada funciona como se fosse executado a primeira vez. Obs: CertFreeCertificateContext também é chamado em nossa aplicação depois da assinatura do XML ser concluída, e o Store dos certificados é fechada. Possíveis Soluções Aqui que venho pedir ajuda ao pessoal responsável pelo projeto para não fazer alterações desnecessária ou que não serão aceitas. De imediato pensei em para as pessoas que assinam os XMLs em aplicações externas fica a responsabilidade da validação do CNPJ e o certificado, assim adicionando uma verificação se o evento OnAntesDeAssinar está "Assigned" antes linha 252 e resolvendo esse problema. Ou então a rotina que verifica se o CNPJ é o mesmo do certificado não realizar o envio do PIN quando o tipo for A3 por exemplo // Talvez adicionar um parametro padrão como TDFeWinCrypt.CarregarCertificado; Para TDFeWinCrypt.CarregarCertificado(const EnviarPinSeExistir: Boolean = True); E aqui seguindo a lógica de enviar o parâmetro falso para o CNPJ, até chegar na unit que verifica se os dois CNPJ são os mesmos. function TDFeSSLCryptClass.GetCertCNPJ: String; begin CarregarCertificadoSeVazio(False); Result := FpDadosCertificado.CNPJ; end; Desculpe se ficou muito extenso.