Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 2143 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado (editado)

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.

Editado por Marcos Fernando Barbosa
Estava faltando parte do codigo
Postado

Bom dia.

Quero somente assinar os documentos NFe, NFCe, CTe, CTEOs, BPe, MDFe. 

Assim não preciso utilizar a parte da geração do ACBR, pois tenho certeza que o formato do arquivo que está sendo passado já está correto.

Tenho componente proprio de geração dos documentos citados acima.

 

  • Fundadores
Postado

Tente algo como:

SSL := TDFeSSL.Create(nil);
try
  SSL.SSLCryptLib := libWinCrypt;
  SSL.SelecionarCertificado;
  XMLAssinado := SSL.Assinar(XMLUTF8, 'NFe', 'infNFe');
finally
  SSL.free;
end;
  

(Não testei, fiz de cabeça)

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

  • Administradores
Postado

Obrigado por reportar.

Fechando. Para novas dúvidas, criar um novo tópico.

Consultora SAC ACBr

Juliana Tamizou

Gerente de Projetos ACBr / Diretora de Marketing AFRAC
Ajude o Projeto ACBr crescer - Seja Pro

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  Discord

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil


Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

  • Este tópico foi criado há 2143 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.