Gravar e Recuperar um Certificado Digital em base64

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 239
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp

Gravar e Recuperar um Certificado Digital em base64

Mensagem por malcarli »

Boa tarde, Devs.

Preciso gravar um certificado digital em uma base de dados, sem ter que instalar no windows. Qdo for necessário a utilização do mesmo, recupero o mesmo e faço o consumo na utilização da uma requisição.

Fiz a alguns testes, mas com erro (exemplo abaixo), não sei se estou errando na forma de gravar e/ou recuperar ou na forma de uso no oSoap:setOption(Não sei se é assim que usa sem o repositório do windows)

Obrigado


Att.

Marcelo A. L. Carli
Marília/SP
Capital Nacional do Alimento ®
https://malc-informatica.ueniweb.com
Insta: @malcarli25
Email / Skype: marceloalcarli@gmail.com

Código: Selecionar todos

  // Gravando o certificado 
   cCert:= hb_base64encode(hb_Memoread([D:\teste\certificado.pfx]))
   hb_MemoWrit([cert64.txt], cCert)
.
.
.
.

   //Recuperar o certificado para uso a partir de um Base64
   cCert:= hb_base64Decode(hb_Memoread([D:\teste\cert64.txt]), "11223344")
	
   BEGIN SEQUENCE WITH __BreakBlock()
      oSoap:= Win_OleCreateObject([MSXML2.ServerXMLHTTP.6.0])
      oSoap:setOption(3, cCert) // aqui busca o certificado no formato pfx, que pode ser gravado em base64
      oSoap:SetTimeouts(30000, 30000, 30000, 30000)
      oSoap:Open([POST], cUrl_Token, .F.)
      oSoap:SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")

      oSoap:Send(cBody)
      oSoap:WaitForResponse(5000)

      cRetorno:= oSoap:Responsetext()
   END SEQUENCE
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Gravar e Recuperar um Certificado Digital em base64

Mensagem por sygecom »

Seu erro está no recuperar o PFX que está no BASE64 ou quando tenta usar ele depois de instalado ?
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 239
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp

Gravar e Recuperar um Certificado Digital em base64

Mensagem por malcarli »

Bom dia, Léo,

comparei a gravação e recuperação do base64 e está correto.


O erro está em usar ele em

Código: Selecionar todos

      oSoap:setOption(3, cCert) // aqui busca o certificado no formato pfx, que pode ser gravado em base64

Pesquisei na net, mas não encontrei a solução, mas sei que esta forma está errada.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Gravar e Recuperar um Certificado Digital em base64

Mensagem por Itamar M. Lins Jr. »

Olá!
Teste usando o caminho absoluto e o arquivo PFX
oSoap:setOption(3, "d:\teste\certificado.pfx")

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 239
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp

Gravar e Recuperar um Certificado Digital em base64

Mensagem por malcarli »

Bom dia,

Já havia testado assim e tb não funcionou

usei também esta outra opção, mas sem resultado

Código: Selecionar todos

      oSoap:SetClientCertificate([D:\teste\certificado.pfx])

obrigado
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Gravar e Recuperar um Certificado Digital em base64

Mensagem por sygecom »

Marcelo,
O certificado tem que está instalado, não basta ter ele como PFX apenas, pelo menos é como uso.


pega cn do certificado instalado:

Código: Selecionar todos

Method ctPegaCNCertificado() Class oCTe_SEFAZ
LOCAL oStore, oCertificados
LOCAL cSubjectName:='', cCN:=''
LOCAL mI:=0

TRY
   oStore := CRIA_OBJETO_ACTIVEX( "CAPICOM.Store" )
CATCH
END

IF oStore = Nil
   RETURN('')
ENDIF

oStore:open(IIF(::cCERT_USER_MICRO='USUARIO',_CAPICOM_CURRENT_USER_STORE,_CAPICOM_LOCAL_MACHINE_STORE),'My',_CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED)
oCertificados:=oStore:Certificates()
oStore:Close()

FOR mI=1 TO oCertificados:Count()
   IF oCertificados:Item(mI):SerialNumber = ::cSerialCert
      cSubjectName := oCertificados:Item(mI):SubjectName
   ENDIF
NEXT
cCN:=''
FOR mI:=AT("CN=",cSubjectName)+3 TO LEN(cSubjectName)
   IF SUBS(cSubjectName,mI,1) == ","
      EXIT
   ENDIF
   cCN += SUBS(cSubjectName,mI,1)
NEXT
oCertificados := Nil
oStore := Nil
RETURN(cCN)

exemplo cortado:

Código: Selecionar todos

TRY
   cCERT := ::ctPegaCNCertificado()
CATCH
END
IF EMPTY(cCERT)
   aRETORNO['MSG']:='Não foi possível carregar as informações do certificado.'
   RETURN(aRETORNO)
ENDIF

IF 'https' $ cService
   cUrlWS:=cService
ELSE
   cUrlWS:=::ctLinkWebService(cService)
ENDIF

IF EMPTY(cUrlWS)
   aRETORNO['MSG']:='Webservice não localizado'
   RETURN(aRETORNO)
ENDIF

TRY
   oServerWS:=CRIA_OBJETO_ACTIVEX( _MSXML2_ServerXMLHTTP )
   oServerWS:setOption( 3, 'CURRENT_USER\MY\'+cCERT )
   oServerWS:open('POST', cUrlWS, .F.)
   oServerWS:setRequestHeader('SOAPAction', cSoap )
   oServerWS:setRequestHeader('Content-Type','application/soap+xml; charset=utf-8')
CATCH
   aRETORNO['MSG']:='Não foi possível inicializar a conexão do webservice'
   RETURN(aRETORNO)
END
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 239
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp

Gravar e Recuperar um Certificado Digital em base64

Mensagem por malcarli »

Bom dia Léo,

Desta forma já uso com a classe do Mestre Quintas, mas queria usar sem ter que instalar o certificado, sei que é possível (a dll da unimake, faz isso), mas queria fazer isto em harbour sem instalar e sem usar dll de terceriros. OBg

Vou postar o codigo em harbour usando a dll da unimake, somente para exemplificar

Código: Selecionar todos


 * Criar objeto para pegar exceção do lado do CSHARP
   oExceptionInterop = CreateObject("Unimake.Exceptions.ThrowHelper")

   Try
    * Criar objeto para trabalhar com certificado digital no INTEROP
	  oCertificado := CreateObject("Unimake.Security.Platform.CertificadoDigitalInterop")
	  
    * Carregar o certificado A1 direto do .PFX
	  oCertificado:CarregarCertificadoDigitalA1("D:\enzza\andre_api\certificado.pfx","1104535")	  
  
    * Demonstrar os dados do certificado digital
      ? "ID do Certificado....: ", oCertificado:GetThumbPrint()
      ? "Dados do proprietario: ", oCertificado:GetSubject()
      ? "Numero de Serie......: ", oCertificado:GetSerialNumber()
      ? "Validade Inicial.....: ", oCertificado:GetNotBefore()
      ? "Validade Final.......: ", oCertificado:GetNotAfter()
      ? "Certificado vencido?.: ", oCertificado:Vencido()
      ?
	  
	  Wait 
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Gravar e Recuperar um Certificado Digital em base64

Mensagem por sygecom »

Mestre, eu faço isso. Mas é um artificio de burlar kkkkkkkk

Slavo em BASE64, e tenho a senha do certificado, quando extraio do base64, faça a instalação silenciosa e uso ele. Simples assim
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 239
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp

Gravar e Recuperar um Certificado Digital em base64

Mensagem por malcarli »

Encontrei a solução (não é ainda a que pretendia ou seja sem instalar no repositório do windows, mas por enquanto até encontrar a solução desejada vamos sendo macacos gordos kkk) e está testada e funcionando. Fiz esta rotina completa. Qq dúvida estou a disposição. Está tudo junto: le um arquivo pfx, grava em um txt, recupera e instala silenciosamente no windows

Código: Selecionar todos

Static Function fBuscaCert()
   Local lOk:= .F., oCert, oCapicomStore, cCert:= GetFile({{[Certificados], [*.pfx]}}, [Buscar Certificados], GetCurrentFolder() + [\], .F., .T. )

   // Aqui é onde salvamos no bd, arquivo etc
   cCert:= Hb_base64encode(cCert)
   MemoWrit([cert64.txt], cCert)

   //Recuperar o certificado para uso a partir de um Base64 que pode estar no bd, arquivo etc
   cCert:= Hb_base64Decode(Memoread(GetCurrentFolder() + [\] + [cert64.txt]))

   If !Hb_FileExists(cCert)
      MsgExclamation([Erro assinatura: Arquivo PFX não encontrado.], [Erro])
      Return (.F.)
   Endif
 
   If Upper(Right(cCert, 4)) # [.PFX]
      MsgExclamation([Não é um Arquivo PFX.], [Erro])
      Return (.F.)
   Endif

   If GetProperty([f_Certifica], [Text_Password], [Value]) == NIL .OR. Empty(GetProperty([f_Certifica], [Text_Password], [Value]))
      MsgExclamation([Erro assinatura: Falta senha do arquivo PFX.], [Erro])
      Return (.F.)
   Endif

   // Carregar PFX e instalar via Capicom
   oCert:= Win_OleCreateObject([CAPICOM.Certificate])
   oCert:Load(cCert, Alltrim(GetProperty([f_Certifica], [Text_Password], [Value])), 1, 0) /// aqui carrega o certificado

   If oCert == NIL .or. Empty(oCert)
      MsgExclamation([Erro Assinatura: Certificado não encontrado ou vencido.], [Erro])
      Return (.F.)
   Endif

   BEGIN SEQUENCE WITH __BreakBlock()
      oCapicomStore:= Win_OleCreateObject([CAPICOM.Store])
      oCapicomStore:Open(2, [My], 2)
      oCapicomStore:Add(oCert)  /// aqui instala no repositório automaticamente
      lOk:= .T.
   ENDSEQUENCE

   If !lOk
      MsgExclamation([Erro assinatura: Problemas no uso do certificado.], [Erro])
      Return (.F.)
   Else
      MsgInfo([Certificado Instalado com Sucesso] + hb_OsNewLine() + [Verifique Repositório do Windows], [Sucesso])
   Endif
Return (.T.)
Att.

Marcelo A. L. Carli
Marília/SP
Capital Nacional do Alimento ®
https://malc-informatica.ueniweb.com
Insta: @malcarli25
Email / Skype: marceloalcarli@gmail.com
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Gravar e Recuperar um Certificado Digital em base64

Mensagem por Itamar M. Lins Jr. »

Olá!
Esse técnica é para quem usa protocolo da Microsoft para autenticar.
Acredito que usando OpenSSL não precisa instalar no windows.
O ACBr tem lá como fazer só que usa a linguagem Object Pascal.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Gravar e Recuperar um Certificado Digital em base64

Mensagem por JoséQuintas »

Será que já resolveu isso na assinatura, ou será que nem pensou nisso ?

Se vai precisar de certificado pra assinatura, não adianta resolver da conexão, e vice-versa.
Ou resolve os dois ou nada feito.

Tem também aqueles certificados que só funcionam com instalação especial, através de programa próprio.

Estudei isso há muito tempo atrás, não dava pra resolver tudo por completo, então joguei tudo fora.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Gravar e Recuperar um Certificado Digital em base64

Mensagem por JoséQuintas »

Faltou pra completar:

Está usando isto:

Código: Selecionar todos

  oSoap:= Win_OleCreateObject([MSXML2.ServerXMLHTTP.6.0])
Isso é componente da Microsoft, então tem documentação na Microsoft.
É ver o que isso aceita, pra ver as opções.
Que eu me lembre, ou é instalado ou é PFX.

Tem a OPENSSL no harbour, mas que eu me lembre, não aceita certificado A3/

Tem como criar certificado em memória, mas cai no problema do A3.

Tem a alternativa de PFX, mas ficar toda hora instala/remove, sei lá com esses certificados especiais, vai ter que preparar em uma máquina W98 ou outra opção primeiro.

A API Windows é velha, a Microsoft passou a usar somente NET, e atualizar somente NET.
Até a documentação da Microsoft vém sumindo com o tempo, pra ninguém usar.

Pois é, aos poucos vão acabando as opções de fazer pelo harbour.
Pelo NET faz tudo, e dá pra criar uma DLL em NET pra usar pelo Harbour.
Exemplo disso é a flexdocs.

Nota: A3 é dependente da segurança no Windows. Como segurança vive mudando.... complica via programa.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Gravar e Recuperar um Certificado Digital em base64

Mensagem por Itamar M. Lins Jr. »

Olá!
São a mesma coisa. Só a versatilidade que muda.
O A1 PFX(arquivo) instalar uma vez por ano. Por causa da validade. Pode copiar pra quantos (CPUs) locais precisar.
O A3, (Praticamente o mesmo arquivo) so que gravado no Cartão, Token, tem de 2,3 anos tem que ter no mínimo 1 na loja e outro na contabilidade. OU 1 em cada maquina que emite NFe ou NFCe
PFX muito mais prático. Não tem pq usar win98 nem sei de onde veio essa informação.
ACBr usa os dois(A3,A1)(sem registrar nada no windows) via OpenSSL. Alias, eu vejo o contrário todo mundo usando Curl, OpenSSl. Fugindo da Microsoft.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
malcarli
Usuário Nível 3
Usuário Nível 3
Mensagens: 239
Registrado em: 20 Ago 2015 18:14
Localização: marilia/sp

Gravar e Recuperar um Certificado Digital em base64

Mensagem por malcarli »

Teria algum exemplo utilizando em harbour com o openssl? obg
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Gravar e Recuperar um Certificado Digital em base64

Mensagem por Itamar M. Lins Jr. »

Olá!
Tem na internet usando CURL, aqui no forum também(lembrei agora digitando)
Eu não sei, estou mais lendo e tentando aprender. Pq até aqui não precisei usar, mas num futuro poderei usar.
Acho que tem comunicando com iFood, cartão... aqui no forum.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Responder