Clipper On Line • Ver Tópico - Checagem de assinatura

Checagem de assinatura

Projeto hbNFe (Nota Fiscal Eletronica/Danfe) para [x]Harbour

Moderador: Moderadores

 

Checagem de assinatura

Mensagempor JoséQuintas » 20 Jun 2016 22:03

Achei isto no site da Microsoft, mas ainda em fase de conversão.
Não vai ser muito diferente no Harbour, porque usa classes do XML 5.0
É pra validar a assinatura do XML.

Dim xmldoc As New DOMDocument50
Dim xmldsig As New MXDigitalSignature50
Dim dsigKey As IXMLDSigKey
Dim dataObj As IXMLDOMNode

Const DSIGNS = "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'"
Const INFILE = "signature.verify.dsa.xml"

Private Function WriteLine(ByVal str As String)
    Text1.Text = Text1.Text + str + vbNewLine
End Function
Private Function writeClear()
    Text1.Text = ""
End Function

Private Function LoadXML(ByVal file As String)
    ' Read input xml file and display the content in the text1.
    Path = App.Path + "\" + file
    xmldoc.async = False
    xmldoc.preserveWhiteSpace = True
    xmldoc.validateOnParse = False
    xmldoc.resolveExternals = False
    If xmldoc.Load(Path) = False Then
        WriteLine "Can't load " + Path
        WriteLine "Reason: " + xmldoc.parseError.reason
        LoadXML = False
        Exit Function
    End If
    xmldoc.setProperty "SelectionNamespaces", DSIGNS
    Set xmldsig.signature = xmldoc.selectSingleNode(".//ds:Signature")
    LoadXML = True
End Function

Private Function VerifyXML()
    If xmldsig.signature Is Nothing Then
        WriteLine "Invalid signature."
        VerifyXML = False
        Exit Function
    End If

    Set oKeyInfo = xmldoc.selectSingleNode(".//ds:KeyInfo/ds:KeyValue")
    If oKeyInfo Is Nothing Then
        WriteLine "Invalid <KeyInfo> element."
        VerifyXML = False
        Exit Function
    End If

    Set oPubKey = xmldsig.createKeyFromNode(oKeyInfo)
    If oPubKey Is Nothing Then
        WriteLine "Can't generate public key for verification."
        VerifyXML = False
        Exit Function
    End If

    Set oVerifiedKey = xmldsig.verify(oPubKey)
    If oVerifiedKey Is Nothing Then
        WriteLine "Signature not verified."
    End If

    WriteLine "Signature verified."
    VerifyXML = True
End Function

Private Sub Form_Load()

    writeClear
    WriteLine "Verifyin signature."
    If LoadXML(INFILE) = True Then
        VerifyXML
    End If
End Sub


Durante conversão pra Harbour, fui confirmar aqueles componentes iniciais, aonde eram usados no fonte e.... não encontrei.
Fui no VB, e acrescentei no fonte: "Option Explicit", algo como a checagem -w3 -es2 que existe no Harbour.
E não é que deu erro nas linhas, porque não usa pra bost. nenhuma.
Belo exemplo de colocar lixo em fonte.... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Checagem de assinatura

Mensagempor JoséQuintas » 20 Jun 2016 22:10

Ainda não testado e nem melhorado.
Pra quem tiver tudo na mão e quiser "brincar".

#define DSIGNS "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'"
#define INFILE "signature.verify.dsa.xml"

MEMVAR XmlDoc, XmlDSig

PROCEDURE Main

   PRIVATE XmlDoc, XmlDSig

   XmlDoc  := win_OleCreateObject( "MSXML2.DOMDocument.5.0" )
   XmlDSig := win_OleCreateObject( "MSXML2.MXDigitalDignature.5.0" )

   IF LoadXml( INFILE )
      VerifyXml()
   ENDIF
   RETURN

FUNCTION LoadXml( cFile )

   XmlDoc:Async := .F.
   XmlDoc:PreserveWhiteSpace := .T.
   XmlDoc:ValidateOnParse := .F.
   XmlDoc:ResolveExternals := .F.

   IF XmlDoc:Load( cFile ) == .F.
      MsgExclamation( "Cannot load file. reason " + XmlDoc:ParseError:Reason )
      RETURN .F.
   ENDIF
   XmlDoc:SetProperty( "SelectionNameSpaces", DSIGNS )
   XmlDsig:Signature := XmlDoc:SelectSingleNode( ".//ds:Signature" )
   RETURN .T.

FUNCTION VerifyXml()

   LOCAL oKeyInfo, oPubKey, oVerifiedKey

   IF XmlDSig:Signature == NIL
      MsgExclamation( "Invalid Signature" )
      RETURN .F.
   ENDIF
   oKeyInfo := XmlDoc:selectSingleNode( ".//ds:KeyInfo/ds:KeyValue" )
   IF oKeyInfo == NIL
      MsgExclamation( "Invalid <KeyInfo> Element" )
      RETURN .F.
   ENDIF
   oPubKey := XmlDSig:CreateKeyFromNode( oKeyInfo )
   IF oPubKey == NIL
      MsgExclamation( "Cannot generate public key for verification" )
      RETURN .F.
   ENDIF
   oVerifiedKey := XmlDSig:Verify( oPubKey )
   IF oVerifiedKey == NIL
      MsgExclamation( "Signature not verified" )
      RETURN .F.
   ENDIF
   MsgExclamation( "Signature Ok" )
   RETURN .T.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Checagem de assinatura

Mensagempor JoséQuintas » 21 Jun 2016 15:38

Depois do primeiro teste ok.


#define DSIGNS "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'"

PROCEDURE Main( cFileName )

   ? ChkSignature( cFileName )
   Inkey(0)
   RETURN

FUNCTION ChkSignature( cXml )

   LOCAL XmlDoc, XmlDSig, cXmlRetorno := "Undefined Error"
   LOCAL oKeyInfo, oPubKey, oVerifiedKey, oSignature

   BEGIN SEQUENCE WITH __BreakBlock()
      XmlDoc  := win_OleCreateObject( "MSXML2.DOMDocument.5.0" )
      XmlDSig := win_OleCreateObject( "MSXML2.MXDigitalSignature.5.0" )

      XmlDoc:Async              := .F.
      XmlDoc:PreserveWhiteSpace := .T.
      XmlDoc:ValidateOnParse    := .F.
      XmlDoc:ResolveExternals   := .F.

      IF .NOT. XmlDoc:Load( cXml )
         cXmlRetorno := "Cannot load file. reason " + XmlDoc:ParseError:Reason
         BREAK
      ENDIF
      XmlDoc:SetProperty( "SelectionNamespaces", DSIGNS )
      oSignature := XmlDoc:SelectSingleNode( ".//ds:Signature" )
      IF oSignature == NIL
         cXmlRetorno := "Not Found Signature"
         BREAK
      ENDIF
      XmlDSig:Signature := oSignature
      oKeyInfo := XmlDoc:selectSingleNode( ".//ds:KeyInfo/ds:X509Data" )
      IF oKeyInfo == NIL
         cXmlRetorno := "Invalid <KeyInfo> Element"
         BREAK
      ENDIF
      oPubKey := XmlDSig:CreateKeyFromNode( oKeyInfo )
      IF oPubKey == NIL
         cXmlRetorno := "Cannot generate public key for verification"
         BREAK
      ENDIF
      oVerifiedKey := XmlDSig:Verify( oPubKey )
      IF oVerifiedKey == NIL
         cXmlRetorno := "Signature not verified"
         BREAK
      ENDIF
      cXmlRetorno := "OK"
   END SEQUENCE
   RETURN cXmlRetorno
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Checagem de assinatura

Mensagempor JoséQuintas » 21 Jun 2016 15:42

Faltou dizer: precisa do XML5 instalado.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Checagem de assinatura

Mensagempor JoséQuintas » 21 Jun 2016 18:46

Precisa melhorar a rotina, e pegar mais situações.
Quando a assinatura é inválida, gera erro de run-time e isso causa retornar "erro desconhecido".
Acaba deixando na dúvida se a rotina falhou ou se é erro de assinatura mesmo.

Neste momento imagino deixar o :Verify em bloco de erro separado do restante.
Ainda não sei se vai precisar mais partes separadas em bloco de erro próprio.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Checagem de assinatura

Mensagempor JoséQuintas » 21 Jun 2016 18:53

Idéia:

   ...
   cXmlRetorno := "Bad Signature or Digest Value"
   oVerifiedKey := XmlDSig:Verify( oPubKey )
   IF oVerifiedKey == NIL
      cXmlRetorno := "Signature not verified"
      BREAK
   ENDIF
   cRetorno := "OK"
END SEQUENCE
RETURN cRetorno


Se der erro, vai retornar "Bad Signature or Digest Value", porque sai do BEGIN/END, e mantém o último conteúdo em cXmlRetorno.
Se seguir em frente, e der NIL, mostra "SIgnature not verified"
E se for até o fim, vai retornar "OK".

Dá até pra usar esse esquema no restante, aonde for preciso.

Agora é testar com muitos XMLs pra pegar mais situações.

Nota: neste último teste, que gerou erro de run-time, apenas troquei duas letras do XML por "XX", pra tornar a assinatura inválida.

Nota2:
oKeyInfo := XmlDoc:selectSingleNode( ".//ds:KeyInfo/ds:X509Data" )


Não pensem que sou expert nessas coisas, que não sou, isso foi no chute mesmo.
Me pareceu que o segundo ds: era um sub-elemento. Coloquei igual está no XML e deu certo..... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Checagem de assinatura

Mensagempor janio » 21 Jun 2016 20:43

JoseQuintas escreveu:
Faltou dizer: precisa do XML5 instalado.


Sem ter nada a ver com o assunto (ou talvez tenha), em uma rotina para consultar o CNPJ na receita federal, tem dado erro na rotina abaixo:

   Try
      oServer:= CreateObject( "MSXML2.ServerXMLHTTP.5.0")
   Catch
      MsgStop('Erro na Criação do Serviço','Consulta')
      Return aRetorno
   End



Em todos os computadores que já testei sempre deu certo, mas em um especificamente tem dado erro: "ERRO NA CRIÇÃO DO SERVIÇO"!

Não consegui identificar o que essa maquina tem (ou não tem) que faz essa rotina não funcionar nela!

Tem ideia do que pode ser?

Janio
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar de usuário

janio
Colaborador

Colaborador
 
Mensagens: 1835
Data de registro: 06 Jul 2004 07:43
Cidade/Estado: UBAJARA - CE
Curtiu: 8 vezes
Mens.Curtidas: 68 vezes

Checagem de assinatura

Mensagempor JoséQuintas » 21 Jun 2016 21:48

Sim, para o tem a ver, e para o ter idéia... rs

O final 5.0 indica XML 5.0.
Isso não vém instalado no Windows. Só saiu como parte do Office.

Como usa CreateObject() é provável que use o xHarbour, então troque o 5.0 por 6.0.
O 5.0 é especial que vém no Office, é o único que trata assinatura digital.
Se isso não envolve assinatura/certificado, melhor o 6.0 que faz parte do Windows.

Notas:
Se for Harbour, e win_OleCreateObject(), nem precisa versão, já seleciona automático o que for preciso.
Pelo menos pra Fazenda/NFE, tem webservice que exige 5.0 ou 6.0, então é possível que algo no servidor possa obrigar determinada versão.
O ACBR também usa isso, talvez tenha instalado ACBR nas outras máquinas, o que já instalou o XML 5.0.
E se mexer com certificado/assinatura, também a CAPICOM.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Checagem de assinatura

Mensagempor JoséQuintas » 22 Jun 2016 10:03

Ainda testando a rotina de checagem.
Por enquanto um teste encima de notas recentes, mas direto no XML autorizado, o que não seria correto.
O resultado foi este:

TipoXml  OK      ERRO
110100   1713    178   
110111     30      2   
110110     70      3   


Acusou assinatura inválida em 10% dos XMLs. Depois vou tentar descobrir o motivo.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes




Retornar para Projeto hbNFe

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 3 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro