Ir para conteúdo
  • Cadastre-se

Marcos Fernando Barbosa

Membros
  • Total de ítens

    10
  • Registro em

  • Última visita

1 Seguidor

Últimos Visitantes

O bloco dos últimos visitantes está desativado e não está sendo visualizado por outros usuários.

Marcos Fernando Barbosa's Achievements

Rookie

Rookie (2/14)

  • Collaborator Rare
  • First Post
  • Week One Done
  • One Month Later
  • One Year In

Recent Badges

1

Reputação

  1. Bom dia. Primeiro passo é validar se usuário que está usando certificado é o próprio. Como o certificado é pessoal na nossa concepção outro usuário não emprestaria o mesmo para um outro usuário. Segundo passo é validar o certificado do usuário em uma base de dados remota com autenticação de duas pontas, para segurança do sistema através de web service. Já tinha feito esta validação antes com a CAPICOM, mas como a mesma não suporta aplicação de windows 64 bits estamos migrando para wincrypt. function GetCertificado: boolean; var Store: TStore; iStore: IStore3; CertsLista, CertsSelecionado: ICertificates2; CertDados: ICertificate; lSigner: TSigner; lSignedData: TSignedData; Cert: TCertificate; Ov: OleVariant; Certificado: TCertificado; xml, s, sFilename: string; ClaWSCertificado: TClaWSCertificadoMG; Arquivo: TStringList; ok: boolean; Read : TLOGINRead; begin Result := false; if not IsInternetConnected then begin MsgErro('Rede indisponível.'); Exit; end; SetBusy(true); Store := CreateComObject as IStore3; try Store.Open(CAPICOM_CURRENT_USER_STORE, 'root', CAPICOM_STORE_OPEN_READ_ONLY); except On E: Exception do begin MsgErro('Erro ao tentar realizar leitura do Certificado Digital'#13 +'Verifique se as cadeias referente ao Certificado Digital'#13 +'estão instaladas de forma correta no PC/NOTEBOOK.'#13 +'Caso a mensagem apresentada abaixo seja erro de registro'#13 +'da dll Capicom.dll entre em contato com suporte'#13 +e.Message); SetBusy(false); 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 RegUsuario.Mensagem := 'Operação cancelada pelo usuário!'; SetBusy(false); 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 RegUsuario.Mensagem := 'Erro na autenticação do Certificado Digital!'; SetBusy(false); Exit; end; end; Cert := TCertificate.Create(nil); Ov := IInterface(CertsSelecionado.Item[1]) as ICertificate2; Cert.ConnectTo(IDispatch(Ov) as ICertificate2); Certificado.IssuerName := Cert.IssuerName; Certificado.ChaveEncode := Cert.Export(CAPICOM_ENCODE_BASE64); xml := ''; s := '<DADOS>' + '<X509Certificate>' + Certificado.ChaveEncode + '</X509Certificate>' + '<IP>' + GetLocalIP + '</IP>' + '</DADOS>'; //AUTENTICAÇÃO DO CERTIFICADO NO WEB SERVICE DE DUAS PONTAS ClaWSCertificado := TClaWSCertificado.Create; ClaWSCertificado.Texto := s; ok := ClaWSCertificado.Execute; if ok then begin Arquivo := ClaWSCertificado.Xml; Arquivo.SaveToFile(sFilename); Read := TLOGINRead.Create; Read.XML := sFilename; ok := Read.LerXml; if (ok) and (RegUsuario.Status = 'SUCESSO') then begin Result := True; end; DeleteFile(Read.XML); Read.Free; end; ClaWSCertificado.Free; lSignedData.Free; lSigner.Free; end; Store.Close; SetBusy(false); end;
  2. Nem exemplo de como validar o pin do certificado com wincrypt consegui encontrar.
  3. Bom dia, lá em nenhum momento não consegui identificar a validação do pin do usuário.
  4. Estou desenvolvendo uma função onde ao selecionar um determinado certificado digital é necessário checar o pin do mesmo. unit ANMsg; interface Uses SysUtils, WinTypes, Vcl.Forms, Vcl.Dialogs, System.UITypes; procedure Mostrar(const s: string); procedure MsgAdverte(const Msg: String); procedure MsgInforma(const Msg: String); procedure MsgErro(const Msg: String); function MsgConfirma(const Msg: String): Boolean; function Confirm(const Msg: String): Boolean; implementation procedure Mostrar(const s: string); begin Application.MessageBox(pchar(s), '', 0); end; procedure MsgErro(const Msg: String); begin Application.MessageBox(PChar(Msg), 'Erro', MB_OK + MB_ICONERROR); end; procedure MsgInforma(const Msg: String); begin Application.MessageBox(PChar(Msg), 'Informação', MB_OK + MB_ICONINFORMATION); end; procedure MsgAdverte(const Msg: String); begin Application.MessageBox(PChar(Msg), 'Advertência', MB_OK + MB_ICONWARNING); end; function MsgConfirma(const Msg: String): Boolean; begin Result := MessageDlg(Msg, mtConfirmation, [mbYes, mbNo], 0) = mrYes; end; function Confirm(const Msg: String): Boolean; begin Result := MessageDlg(Msg, mtConfirmation, [mbYes, mbNo], 0) = mrYes; end; end. ----------------------------------------------------------------------------------------------------------------- unit AnCryptUtil; interface uses Windows, Messages, SysUtils, Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.ComCtrls, Vcl.Buttons, ShellApi, WinCrypt, NCrypt, BCrypt; function GetCSPProviderParamDWord(ACryptProvider: HCRYPTPROV; dwParam: DWORD): DWORD; function GetCNGProviderParamDWord(ACryptHandle: NCRYPT_HANDLE; dwParam: LPCWSTR): DWORD; function GetCNGProviderIsHardware(ACryptHandle: NCRYPT_HANDLE): Boolean; function GetCSPProviderIsHardware(ACryptProvider: HCRYPTPROV): Boolean; function GetProviderOrKeyIsHardware(ProviderOrKeyHandle: HCRYPTPROV_OR_NCRYPT_KEY_HANDLE; dwKeySpec: DWORD): Boolean; function GetCertIsHardware(ACertContext: PCCERT_CONTEXT): Boolean; function CheckPINError(WinErro: Integer; RaiseUnknown: Boolean): Boolean; implementation function GetCSPProviderParamDWord(ACryptProvider: HCRYPTPROV; dwParam: DWORD): DWORD; var pdwDataLen: DWORD; begin pdwDataLen := SizeOf(DWORD); if not CryptGetProvParam(ACryptProvider, dwParam, @Result, pdwDataLen, 0) then raise Exception.Create('GetCSPProviderParamDWord. Erro: criptografia'); end; function GetCNGProviderParamDWord(ACryptHandle: NCRYPT_HANDLE; dwParam: LPCWSTR): DWORD; var pdwDataLen, pcbResult: DWORD; Ret: SECURITY_STATUS; begin Result := 0; pdwDataLen := SizeOf(DWORD); pcbResult := 0; Ret := NCryptGetProperty(ACryptHandle, dwParam, @Result, pdwDataLen, pcbResult, 0); if (Ret <> ERROR_SUCCESS) then raise Exception.Create('GetCNGProviderParamDWord. Erro: '+IntToHex(Ret, 8)); end; function GetCNGProviderIsHardware(ACryptHandle: NCRYPT_HANDLE): Boolean; var ImpType: DWORD; begin try ImpType := GetCNGProviderParamDWord(ACryptHandle, NCRYPT_IMPL_TYPE_PROPERTY); Result := ((ImpType and NCRYPT_IMPL_HARDWARE_FLAG) = NCRYPT_IMPL_HARDWARE_FLAG); except Result := True; // TODO: Assumindo que todos certificados CNG são A3 end; end; function GetCSPProviderIsHardware(ACryptProvider: HCRYPTPROV): Boolean; var ImpType: DWORD; begin ImpType := GetCSPProviderParamDWord(ACryptProvider, PP_IMPTYPE); Result := ((ImpType and CRYPT_IMPL_HARDWARE) = CRYPT_IMPL_HARDWARE); end; function GetProviderOrKeyIsHardware(ProviderOrKeyHandle: HCRYPTPROV_OR_NCRYPT_KEY_HANDLE; dwKeySpec: DWORD): Boolean; begin if dwKeySpec = CERT_NCRYPT_KEY_SPEC then Result := GetCNGProviderIsHardware(ProviderOrKeyHandle) else Result := GetCSPProviderIsHardware(ProviderOrKeyHandle); end; function GetCertIsHardware(ACertContext: PCCERT_CONTEXT): Boolean; var dwKeySpec: DWORD; pfCallerFreeProv: LongBool; ProviderOrKeyHandle: HCRYPTPROV_OR_NCRYPT_KEY_HANDLE; begin Result := False; ProviderOrKeyHandle := 0; dwKeySpec := 0; pfCallerFreeProv := False; // Obtendo o Contexto do Provedor de Criptografia do Certificado // if not CryptAcquireCertificatePrivateKey( ACertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, Nil, ProviderOrKeyHandle, dwKeySpec, pfCallerFreeProv) then raise Exception.Create('Erro do provedor de criptografia'); try Result := GetProviderOrKeyIsHardware(ProviderOrKeyHandle, dwKeySpec); finally if pfCallerFreeProv then Result := CryptReleaseContext(ProviderOrKeyHandle, 0); if not Result then raise Exception.Create('Erro do contexto do certificado'); end; end; function CheckPINError(WinErro: Integer; RaiseUnknown: Boolean) :Boolean; begin Result := true; if WinErro = NO_ERROR then Result := False else if WinErro = ERROR_NO_TOKEN then begin raise Exception.Create('Token ou cartão inteligente não encontrado.'); end else if WinErro = SCARD_W_WRONG_CHV then begin raise Exception.Create('O cartão não pode ser acessado porque o PIN errado foi apresentado.'); end else if WinErro = SCARD_W_CHV_BLOCKED then begin raise Exception.Create('O cartão não pode ser acessado porque o número máximo de tentativas de entrada de PIN foi atingido'); end else if (WinErro > 0) and ((WinErro <> ERROR_NO_TOKEN) and (WinErro = SCARD_W_WRONG_CHV) and (WinErro = SCARD_W_CHV_BLOCKED)) then begin if RaiseUnknown then begin raise Exception.Create('Falha ao Definir PIN do Certificado'); end; end; end; end. -------------------------------------------------------------------------------------------------------------------------------------------- unit CheckCertificado2; interface uses Windows, Messages, SysUtils, Classes, ShellApi, WinCrypt, NCrypt, BCrypt, AnCryptUtil, AnMsg; function CheckCertificado: boolean; implementation function GetCertificado: boolean; var hStore: HCERTSTORE; ACertContext: PCCERT_CONTEXT; inUse : PCERT_RDN; LKeyHandle: HCRYPTPROV_OR_NCRYPT_KEY_HANDLE; j, k: DWORD; n: Pointer; b: BOOL; ProviderOrKeyHandle: HCRYPTPROV_OR_NCRYPT_KEY_HANDLE; Ret: Integer; Reader: PByte; ReaderSize: DWORD; begin Result := False; hStore := nil; try hStore := CertOpenSystemStore(0, 'My'); ACertContext := CryptUIDlgSelectCertificateFromStore(hStore, 0, 'Selecione um Certificado', 'Selecione o Certificado que deseja utilizar:', CRYPTUI_SELECT_LOCATION_COLUMN or CRYPTUI_SELECT_ISSUEDBY_COLUMN or CRYPTUI_SELECT_INTENDEDUSE_COLUMN, 0, Nil); if (Assigned(ACertContext)) and (ACertContext <> nil) and (GetCertIsHardware(ACertContext)) then begin //checa se certificado digital tem chave privada if CryptAcquireCertificatePrivateKey(ACertContext, j, n, LKeyHandle, k, b) then begin MsgAdverte('Certificado foi selecionado. Certificado tem chave privada. Drivers do certificados encontrados'); if not GetCNGProviderIsHardware(ProviderOrKeyHandle) then Exit; MsgAdverte('provedor do serviços de criptografia recuperado com sucesso'); //não identifiquei qual função usar para validar o pin do usuario nas libs WinCrypt, NCrypt, BCrypt, tentei usar a função abaiaxo sem sucesso // Ret := NCryptSetProperty(ProviderOrKeyHandle, NCRYPT_PIN_PROPERTY, Reader, ReaderSize, 0); // MsgAdverte(Ret.ToString); // if CheckPINError(Ret, true) then // Exit; end else RegUsuario.Mensagem := 'Drivers do certificado não encontrados'; end else begin RegUsuario.Mensagem := 'Operação cancelada pelo usuário'; end; finally CertCloseStore(hStore, 0); end; end; Alguém ai poderia dar um help
  5. 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.
  6. 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.
  7. Ao tentar utilizar o componente ACBrDFeSSL com o codigo abaixo dá a seguinte mensagem de erro : erro não especificado. O arquivo já vem montado com as tags de forma correta. O que pode estar errado? function AssinaDocXml2(const FileXml, Id: string; var FileOut: string): Boolean; var A: TDFeSSL; B : TDFeSSLXmlSignMsXml; I: Integer; fileXmlNew : string; AXml: AnsiString; begin fileXmlNew := MontaFileXml(FileXml, Id); AXml := AnsiString(WideString(fileXmlNew)); A := TDFeSSL.Create; A.SSLCryptLib := cryCapicom; A.SelecionarCertificado; B := TDFeSSLXmlSignMsXml.Create(A); with TStringList.Create do try // carrega o XML de template Add(AXml); // obtém o XML assinado no Text do StringList Text := B.Assinar(Text, 'Assinatura', ''); // salva o XML em disco SaveToFile(FileOut); finally Free; end; A.Free; end;
  8. Cara é um projeto mais simples, tem coisa demais no ACBR que não preciso utilizar, por isso da solução mais simples uXMLAssina.pas
  9. Alguém sabe o porque que da erro desconhecido quando chega no bloco: try signedKey := xmldsig.sign(dsigKey,NOKEYINFO); if (signedKey = nil) then begin MsgErro('Assinatura Falhou.'); Result := False; Exit; end; except on e: Exception do begin MsgErro('Erro durante a assinatura ->' + sLineBreak + e.Message); Result := False; Exit; end; end; uXMLAssina.pas
×
×
  • 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.

The popup will be closed in 10 segundos...