Clipper On Line • Ver Tópico - Assinar texto/arquivo com certificado digital pelo windows

Assinar texto/arquivo com certificado digital pelo windows

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

 

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor dbsh » 04 Out 2017 14:05

Gera DigestValue, SignatureValue, X509 para incluir em XML
DigestValue = Hash SHA256/SHA512, entre outros
SignatureValue = DigestValue assinado

Assina texto/arquivo digitalmente

#pragma /es3
#pragma /w3

#define __TESTE__

//xp, window vista, 2003 server ou posterior
//Capicom.dll - Capicom 2.0 - Capicom.h

#define CAPICOM_HASH_ALGORITHM_SHA1     0
#define CAPICOM_HASH_ALGORITHM_MD2      1
#define CAPICOM_HASH_ALGORITHM_MD4      2
#define CAPICOM_HASH_ALGORITHM_MD5      3
#define CAPICOM_HASH_ALGORITHM_SHA_256  4
#define CAPICOM_HASH_ALGORITHM_SHA_384  5
#define CAPICOM_HASH_ALGORITHM_SHA_512  6

#define CAPICOM_ENCRYPTION_ALGORITHM_RC2  0
#define CAPICOM_ENCRYPTION_ALGORITHM_RC4  1
#define CAPICOM_ENCRYPTION_ALGORITHM_DES  2
#define CAPICOM_ENCRYPTION_ALGORITHM_3DES 3
#define CAPICOM_ENCRYPTION_ALGORITHM_AES  4 // v2.0

#define CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM  0
#define CAPICOM_ENCRYPTION_KEY_LENGTH_40_BITS  1
#define CAPICOM_ENCRYPTION_KEY_LENGTH_56_BITS  2
#define CAPICOM_ENCRYPTION_KEY_LENGTH_128_BITS 3
#define CAPICOM_ENCRYPTION_KEY_LENGTH_192_BITS 4 // AES v2.0
#define CAPICOM_ENCRYPTION_KEY_LENGTH_256_BITS 5 // AES v2.0

#define CAPICOM_ENCODE_ANY    0xffffffff
#define CAPICOM_ENCODE_BASE64 0
#define CAPICOM_ENCODE_BINARY 1

#define CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT 0
#define CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN       1
#define CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY   2

#define CAPICOM_LOCAL_MACHINE_STORE          1
#define CAPICOM_CURRENT_USER_STORE           2
#define CAPICOM_STORE_OPEN_READ_ONLY         0
#define CAPICOM_STORE_OPEN_READ_WRITE        1
#define CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED   2
#define CAPICOM_CERTIFICATE_FIND_SHA1_HASH   0
#define CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME 0

#define CAPICOM_VERIFY_SIGNATURE_ONLY 0

#ifdef __TESTE__
PROCEDURE TesteCapicom
LOCAL sTexto, aAss, sCript, sDescript, DigestValue, SignatureValue, x509

sTexto         := "texto a ser gerado hash, no caso de arquivo, carregue o arquivo e passe para esta funcao"

DigestValue    := HashCapicom( sTexto )
aAss           := SignatureCapicom( DigestValue )
SignatureValue := aAss[1]
X509           := aAss[2]

HB_SYMBOL_UNUSED( x509 )

?
? DigestValue == CHKSignatureCapicom( SignatureValue )
? IsValidSignatureCapicom( DigestValue, SignatureValue )

sCript    := CriptCapiCom( sTexto, DigestValue, 4, 5 )
sDescript := DescriptCapiCom( sCript, DigestValue, 4, 5 )

?
? sDescript == sTexto

//sCript    := criptCapiCom( sTexto, PafChavePrivada(), 4, 5 )
//sDescript := DescriptCapiCom( sCript, PafChavePublica(), 4, 5 )

?
? sDescript == sTexto

wait
RETURN
#endif

//Esta função só cria um hash da string passada como parâmetro
FUNCTION HashCapicom( sTexto, AlgoritimoHash  )
LOCAL objHash

IF sTexto = NIL
   sTexto := DToS(Date()) + Time()
ENDIF

IF AlgoritimoHash = NIL
   AlgoritimoHash := CAPICOM_HASH_ALGORITHM_SHA_256
ENDIF

objHash := CreateObject("CAPICOM.HashedData.1")
objHash:Algorithm := AlgoritimoHash
objHash:Hash( sTexto )

RETURN objHash:Value

//Esta função assina string passada como parâmetro
//DigestValue = Hash Gerado por HashCapicom
FUNCTION SignatureCapicom( DigestValue, Cert, Encode )
LOCAL SignedData, CertBase64, Signer, sRet, TimeAttrib

//System.Security.Cryptography.Pkcs

IF DigestValue = NIL
   RETURN NIL
ENDIF

IF Encode = NIL
   Encode := CAPICOM_ENCODE_BASE64
ENDIF

//Signer := CreateObject("CAPICOM.Signer.1")  //versao 1
Signer := CreateObject("CAPICOM.Signer.2")  //versao 2

IF Cert = NIL
   Cert := SelecionaCertificadoCapicom()
   IF Cert = NIL
      RETURN NIL
   ENDIF
   Signer:Certificate := cert
ELSE
   Signer:Certificate := cert:DefaultInterface
ENDIF

IF !(Signer:Certificate:HasPrivateKey ;
   .and. DToS(Signer:Certificate:ValidFromDate) <= DToS(Date()) ;
   .and. DToS(Signer:Certificate:ValidToDate) >= DToS(Date()) )
   RETURN NIL
ENDIF

Signer:Options := CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT

//usado na chave <X509Certificate>
CertBase64 := Signer:Certificate:Export(CAPICOM_ENCODE_BASE64)
CertBase64 := Trim(StrTran(certBase64, Chr(13) + Chr(10), ''))

TimeAttrib :=  CreateObject("CAPICOM.Attribute")
TimeAttrib:Name := CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
TimeAttrib:Value = DateTime()

Signer:AuthenticatedAttributes:Add(TimeAttrib)

SignedData := CreateObject("CAPICOM.SignedData.1")
SignedData:Content := DigestValue

//segundo parametro falso, apenas retona assinatura do texto, não inclui no texto
sRet := SignedData:Sign(Signer, .F., Encode)

RETURN {sRet, CertBase64}

//Esta função retorna Hash sem Assinatura
//sAss = Hash Assinada
FUNCTION CHKSignatureCapicom( sAss )
LOCAL SignedData

IF sAss = NIL
   RETURN NIL
ENDIF

SignedData := CreateObject("CAPICOM.SignedData.1")
SignedData:Verify( sAss, .F., CAPICOM_VERIFY_SIGNATURE_ONLY);

RETURN SignedData:Content

//Esta função Verifica se assinatura e valida
//DigestValue = Hash
//SignatureValue = Hash Assinada
FUNCTION IsValidSignatureCapicom( DigestValue, SignatureValue )

IF DigestValue = NIL .or. SignatureValue = NIL
   RETURN .F.
ENDIF

RETURN CHKSignatureCapicom( SignatureValue ) == DigestValue

//carrega certificado digital
FUNCTION SelecionaCertificadoCapicom()
LOCAL MyStore, Certificates

MyStore := CreateObject("CAPICOM.Store")
MyStore:Open(CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY)

begin sequence with {|| Break() }
   Certificates := MyStore:Certificates:Select("Selecione um certificado digital","Algoritimo de Assinatura SHA256RSA")
recover
   RETURN NIL
end

IF MyStore:certificates:Count = 0
   RETURN NIL
ENDIF

RETURN certificates:Item(1)

010011110010000001110011011101010110001101100101011100110111001101101111001000001110100100100000011000110110111101101110011100110111010001110010011101011110110101100100011011110010000001100001001000000110111001101111011010010111010001100101
01001101011000010111001001100011011011110111001100100000010000010110111001110100011011110110111001101001011011110010000001000100011001010010000001000010011011110110111001101001
0101010001100101011011000011101000100000001010000011001000110111001010010011100100101101001110010011100000110100001100110010110100110101001100100011100100110000
Avatar de usuário

dbsh
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 115
Data de registro: 14 Jul 2004 14:19
Cidade/Estado: ES
Curtiu: 2 vezes
Mens.Curtidas: 15 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor JoséQuintas » 05 Out 2017 14:58

Legal.
Testar isso pra ver se bate com a assinatura que uso hoje.
Se isso eliminar a necessidade do MSXML5 vai ser bom.
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: 18007
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor JoséQuintas » 10 Out 2017 19:13

Ainda não comparei com a que uso pra assinar XML, mas coloquei na pasta de rascunhos (drafts) da Sefazclass.
Fonte modificado e usando classe.

https://github.com/JoseQuintas/sefazclass/blob/master/drafts/assinaturacapicom.prg

Até aproveitei pra criar um CH completo da CAPICOM, com tudo que pude encontrar.
Pode ser útil pra qualquer fonte que use CAPICOM.

https://github.com/JoseQuintas/sefazclass/blob/master/include/capicom.ch

Lembrando que, como está na pasta da sefazclass, pra quem usar, basta indicar sefazclass.hbc (e mais o #include lógico)
Neste caso a indicação da sefazclass só vai servir pra indicar aonde encontrar o arquivo capicom.ch e nada mais.
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: 18007
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor JoséQuintas » 10 Out 2017 19:15

A propósito....
O Harbour tem funções de hash.
Caso dê certo, talvez dê pra fazer pelo Harbour, e só reste a assinatura mesmo.
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: 18007
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor AlainSilva » 04 Dez 2017 10:04

Ola bom dia, sou novo no fórum. Estou usando a classe e estou tendo o seguinte erro:
METHOD HashData( cData, nAlgorithm ) CLASS CapicomClass
LOCAL oCapicom
IF cData = NIL
cData := DToS( Date() ) + Time()
ENDIF
IF nAlgorithm = NIL
nAlgorithm := CAPICOM_HASH_ALGORITHM_SHA_256
ENDIF
oCapicom := CreateObject("CAPICOM.HashedData.1")
oCapicom:Algorithm := nAlgorithm
oCapicom:Hash( cData )
RETURN oCapicom:Value

Error occurred at: 04/12/2017, 08:50:26
   Error description: Error CAPICOM.HashedData.1/9  The HashedData object does not contain hashed value.
: _ALGORITHM
   Args:
     [   1] = N   4

Seria a versão da capicom.dll? Se for onde baixo essa dll?
Obrigado
AlainSilva
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 12
Data de registro: 04 Dez 2017 09:47
Cidade/Estado: Rancharia/SP
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor Daniel » 04 Dez 2017 11:56

Daniel

Harbour + Minigui + dbfcdx
Marinas-Gui Pena que parou o suporte
Avatar de usuário

Daniel
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 373
Data de registro: 13 Ago 2003 22:42
Cidade/Estado: Apucarana - PR
Curtiu: 0 vez
Mens.Curtidas: 36 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor AlainSilva » 04 Dez 2017 13:26

Ola Daniel, não adiantou, atualizei, alias era a que eu já tinha, registrei e o erro continua.
Não aceita o oCapicom:Algorithm := nAlgorithm (nAlgorithm = 4 )
Error description: Error CAPICOM.HashedData.1/9 The specified encryption algorithm is invalid.
: _ALGORITHM
Args:
[ 1] = N 4
AlainSilva
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 12
Data de registro: 04 Dez 2017 09:47
Cidade/Estado: Rancharia/SP
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor Daniel » 04 Dez 2017 15:18

você tem certeza que esta pegando a versão nova?
pelo cmd usa este comando na pasta raiz
dir /s capicom.dll
ele vai mostra onde as capicom.dll esta
Daniel

Harbour + Minigui + dbfcdx
Marinas-Gui Pena que parou o suporte
Avatar de usuário

Daniel
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 373
Data de registro: 13 Ago 2003 22:42
Cidade/Estado: Apucarana - PR
Curtiu: 0 vez
Mens.Curtidas: 36 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor AlainSilva » 04 Dez 2017 16:08

Sim Daniel, é a mesma que eu uso pra nfe. Registrei regsvr32 capicom
.DLL certinho. O detalhe é que estou utilizando o xbarbour e não o harbour. Será que pode ser isso? O sha1 vai de boa. Sha256 da pau.
AlainSilva
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 12
Data de registro: 04 Dez 2017 09:47
Cidade/Estado: Rancharia/SP
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor Daniel » 04 Dez 2017 16:24

tem esta linha
#define CAPICOM_HASH_ALGORITHM_SHA_256 4
se tiver ai e erro no xHarbour
testei aqui deu certo

testa assim pra ver se da certo
FUNCTION HashCapicom(stexto, AlgoritimoHash   )
   LOCAL objHash

   IF sTexto = NIL
      sTexto := DToS(Date()) + Time()
   ENDIF

   IF AlgoritimoHash = NIL
      AlgoritimoHash := 4
   ENDIF

   objHash := CreateObject("CAPICOM.HashedData.1")
   objHash:Algorithm := AlgoritimoHash
   objHash:Hash( sTexto )

   RETURN objHash:Value
Daniel

Harbour + Minigui + dbfcdx
Marinas-Gui Pena que parou o suporte
Avatar de usuário

Daniel
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 373
Data de registro: 13 Ago 2003 22:42
Cidade/Estado: Apucarana - PR
Curtiu: 0 vez
Mens.Curtidas: 36 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor JoséQuintas » 04 Dez 2017 18:01

Problema 1: dependendo da versão da CAPICOM, ela não tem o algorítmo SHA256

Problema 2: XHARBOUR, LIBs e BORLAND C

Por mais que se fale.... não adianta... volta sempre a mesma questão.

XHarbour... é interessante... mas não tem atualização, tem problemas.
LIBs... tentam consertar o XHarbour... cada uma faz de um jeito a mesma coisa...
Borland C... permite rotinas duplicadas no EXE... ou seja, nunca se sabe o que vai ser executado, pode ser a rotina certa, pode ser a rotina errada...

Tente num fonte em separado, antes de acrescentar ao aplicativo.
De preferência, CONSOLE, pra não precisar de nenhuma LIB Lixo.

Se assim funcionar, aí avise a LIB Lixo pra ser corrigida.
Avisar XHarbour não adianta... nunca mais vão corrigir nada nele....
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: 18007
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor AlainSilva » 05 Dez 2017 07:08

Bom dia, Daniel eu já tinha feito isso de passar o valor direto para a variável mas o erro persiste. Bom, primeiro acho que preciso saber se estou com a capicom correta.
Se possível tem como me enviar a capicom que tem o algoritimo sha256?
meu email: alainsilva73@gmail.com

Minha capicom: data: 11/04/2007 CAPICOM.DLL tam: 511.328 bytes

Agora se eu estiver a capicom correta e o problema for o xharbour não tem outra opção, vou ter que passar a usar o harbour.
AlainSilva
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 12
Data de registro: 04 Dez 2017 09:47
Cidade/Estado: Rancharia/SP
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor JoséQuintas » 05 Dez 2017 09:18

O que faço sempre é tentar fazer o programador usar a cabeça.
Não precisa acreditar no que escrevem, e também não adianta nada virar "copiador de fonte".

Isso não é nada do outro mundo, é relativamente simples.
MICROSOFT FORNECE ÚLTIMA CAPICOM.

uma rápida pesquisa no google sobre capicom e sha256:

capicom.png


O primeiro link aberto

capicom2.png


Uma pesquisa de capicom download

capicom3.png


Olhem só que interessante....
O KIT CAPICOM da Microsoft vém até com muitos exemplos.
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: 18007
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor AlainSilva » 05 Dez 2017 16:20

Obrigado pela ajuda, consegui rodar a rotina, vou fazer mais testes.
AlainSilva
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 12
Data de registro: 04 Dez 2017 09:47
Cidade/Estado: Rancharia/SP
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Assinar texto/arquivo com certificado digital pelo windows

Mensagempor AlainSilva » 06 Dez 2017 13:19

boa tarde, como eu já tenho as funções da nfe e do manifesto que utiliza sha1, estou fazendo os testes pra ver se assinatura fica igual.
Percebi o seguinte. O xml seria esse:
cTexto := '<envEvento xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.00"><idLote>1</idLote><evento xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.00"><infEvento Id="ID2102103517115233147700015355001000097206106174393001"><cOrgao>91</cOrgao><tpAmb>2</tpAmb><CNPJ>43198696000468</CNPJ><chNFe>35171152331477000153550010000972061061743930</chNFe><dhEvento>2017-12-06T11:24:08-02:00</dhEvento><tpEvento>210210</tpEvento><nSeqEvento>1</nSeqEvento><verEvento>1.00</verEvento><detEvento versao="1.00"><descEvento>Ciencia da Operacao</descEvento></detEvento></infEvento><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="#ID2102103517115233147700015355001000097206106174393001"><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></evento></envEvento>'

A tag <X509Certificate> traz igual. Já a TAg <DigestValue> na minha rotina sempre traz um valor diferente. por exemplo: em 3 envios do mesmo xml ficou assim:
1vez)SbaWmCq15aemJKCpXeRbqh5padA=
2vez)HKckad0MNEeT5MomesU6eoG936A=
3vez)r8xDsLDicSAsUFTK8JlYacfm2Ko=

Já nessa rotina o cDigestValue é sempre o mesmo e diferente desses: F0D98762598842AE8C61B6CE5A595E397C698D87

obs: eu alterei para sha1 ok ( nAlgorithm := CAPICOM_HASH_ALGORITHM_SHA1 ou 0)
AlainSilva
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 12
Data de registro: 04 Dez 2017 09:47
Cidade/Estado: Rancharia/SP
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Próximo



Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 17 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