Assinar texto/arquivo com certificado digital pelo windows
Moderador: Moderadores
- rochinha
- Administrador

- Mensagens: 4664
- Registrado em: 18 Ago 2003 20:43
- Localização: São Paulo - Brasil
- Contato:
Assinar texto/arquivo com certificado digital pelo windows
Amiguinhos,
ao testar me faltou as funções:
HB_SYMBOL_UNUSED()
CriptCapiCom()
DescriptCapiCom()
ao testar me faltou as funções:
HB_SYMBOL_UNUSED()
CriptCapiCom()
DescriptCapiCom()
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Assinar texto/arquivo com certificado digital pelo windows
Só hoje testei isso.
O mais próximo que cheguei foi alterando a rotina de Hash, mas o digest value não bate.
Sha1, porque está no manual da NFE.
O resto peguei numa rotina da NET.
Falta algum detalhe referente ao XML.
O mais próximo que cheguei foi alterando a rotina de Hash, mas o digest value não bate.
Sha1, porque está no manual da NFE.
O resto peguei numa rotina da NET.
Código: Selecionar todos
IF nAlgorithm = NIL
nAlgorithm := CAPICOM_HASH_ALGORITHM_SHA1 // 256
ENDIF
oUtil := win_OleCreateObject( "CAPICOM.Utilities" )
oCapicom := win_OleCreateObject( "CAPICOM.HashedData.1" )
oCapicom:Algorithm := nAlgorithm
oCapicom:Hash( cData )
RETURN oUtil:Base64Encode( outil:HexToBinary( oCapicom:Value ) )
Se o digestvalue não bate... nem adianta assinar, porque é o digestvalue que é assinado.DigestValue PwA/AD8APwA/AD8APwA/AD8APwA=
DigestValue d/H7RrkNBl1a159pNWFgKKycQ9k=
Falta algum detalhe referente ao XML.
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/
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/
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Assinar texto/arquivo com certificado digital pelo windows
Inclusive tem uma parte, não chega a ser errada, mas é só pra complicar:
Mais prático eliminar isso e usar direto o certificado:
a rotina acima coloca o certificado no "assinador", pra extrair o certificado....Signer := CreateObject("CAPICOM.Signer.2") //versao 2
Signer:Certificate := cert
CertBase64 := Signer:Certificate:Export(CAPICOM_ENCODE_BASE64)
Mais prático eliminar isso e usar direto o certificado:
Cert:Export( CAPICOM_ENCODE_BASE64 )
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/
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/
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Assinar texto/arquivo com certificado digital pelo windows
A rotina alterada:
E a rotina que usei pra teste:
Compilei usando isto:
Código: Selecionar todos
/*
https://pctoledo.org/forum/viewtopic.php?f=43&t=18664
*/
#define __TESTE__
#include "sefaz_capicom.ch"
#include "hbclass.ch"
#ifdef __TESTE__
PROCEDURE TesteCapicom
LOCAL cTexto, cSignatureValue, cDigestValue, cPublicKey
cTexto := "texto a ser gerado hash, no caso de arquivo, carregue o arquivo e passe para esta funcao"
cDigestValue := CapicomClass():HashData( cTexto )
cSignatureValue := CapicomClass():Sign( cDigestValue, , , @cPublicKey )
?
? cDigestValue == CapicomClass():VerifySignature( cSignatureValue )
? IsValidSignatureCapicom( cDigestValue, cSignatureValue )
? cPublicKey
WAIT
RETURN
#endif
FUNCTION IsValidSignatureCapicom( cDigestValue, cSignatureValue )
IF cDigestValue = NIL .OR. cSignatureValue = NIL
RETURN .F.
ENDIF
RETURN CapicomClass():VerifySignature( cSignatureValue ) == cDigestValue
CREATE CLASS CapicomClass
METHOD SelectCertificate()
METHOD VerifySignature( cSignedData )
METHOD HashData( cData, nAlgorithm )
METHOD PublicKey( oCAPICOMCert )
METHOD Sign( cDigestValue, oCAPICOMcert, nEncode, cPublicKey )
END CLASS
METHOD SelectCertificate() CLASS CapicomClass
LOCAL oCapicom, oCertificate
oCapicom:= win_OleCreateObject( "CAPICOM.Store" )
oCapicom:Open( CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY )
BEGIN SEQUENCE WITH { || __BreakBlock() }
oCertificate := oCapicom:Certificates:Select( "Selecione um certificado digital", "Algoritmo de Assinatura SHA256RSA" )
END SEQUENCE
IF oCapicom:Certificates:Count() == 0
RETURN NIL
ENDIF
RETURN oCertificate:Item( 1 )
METHOD VerifySignature( cSignedData ) CLASS CapicomClass
LOCAL oCapicom
IF cSignedData == NIL
RETURN NIL
ENDIF
oCapicom := win_OleCreateObject( "CAPICOM.SignedData.1" )
oCapicom:Verify( cSignedData, .F., CAPICOM_VERIFY_SIGNATURE_ONLY )
RETURN oCapicom:Content
METHOD HashData( cData, nAlgorithm ) CLASS CapicomClass
LOCAL oCapicom, oUtil
IF cData = NIL
cData := DToS( Date() ) + Time()
ENDIF
IF nAlgorithm = NIL
nAlgorithm := CAPICOM_HASH_ALGORITHM_SHA1 // 256
ENDIF
oUtil := win_OleCreateObject( "CAPICOM.Utilities" )
oCapicom := win_OleCreateObject( "CAPICOM.HashedData.1" )
oCapicom:Algorithm := nAlgorithm
oCapicom:Hash( cData )
RETURN oUtil:Base64Encode( outil:HexToBinary( oCapicom:Value ) )
// RETURN oCapicom:Value
METHOD PublicKey( oCapicomCert ) CLASS CapicomClass
LOCAL cPublicKey
//oCapicom := win_OleCreateObject( "CAPICOM.Signer.2" )
//oCapicom:Signer:Certificate := oCAPICOMCert
//oCapicom:Signer:Options := CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT
cPublicKey := StrTran( /* oCapicom:Certificate:*/ oCapicomCert:Export( CAPICOM_ENCODE_BASE64 ), Chr(13) + Chr(10), "" )
RETURN cPublicKey
METHOD Sign( cDigestValue, oCAPICOMCert, nEncode, cPublicKey ) CLASS CapicomClass
LOCAL oCAPICOMSignedData, oCAPICOMSigner, oCAPICOMTimeStamp, cSignature
IF cDigestValue = NIL
RETURN NIL
ENDIF
IF nEncode = NIL
nEncode := CAPICOM_ENCODE_BASE64
ENDIF
oCAPICOMSigner := win_OleCreateObject( "CAPICOM.Signer.2" ) // versao 2
IF oCAPICOMCert = NIL
oCAPICOMCert := ::SelectCertificate()
IF oCAPICOMCert = NIL
RETURN NIL
ENDIF
oCAPICOMSigner:Certificate := oCAPICOMcert
ELSE
oCAPICOMSigner:Certificate := oCAPICOMcert:DefaultInterface
ENDIF
IF ! ( oCAPICOMSigner:Certificate:HasPrivateKey ;
.AND. DToS( oCAPICOMSigner:Certificate:ValidFromDate ) <= DToS( Date() ) ;
.AND. DToS( oCAPICOMSigner:Certificate:ValidToDate ) >= DToS( Date() ) )
RETURN NIL
ENDIF
oCAPICOMSigner:Options := CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT
cPublicKey := StrTran( oCAPICOMSigner:Certificate:Export( CAPICOM_ENCODE_BASE64 ), Chr(13) + Chr(10), "" )
oCAPICOMTimeStamp := win_OleCreateObject( "CAPICOM.Attribute" )
oCAPICOMTimeStamp:Name := CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
oCAPICOMTimeStamp:Value := hb_DateTime()
oCAPICOMSigner:AuthenticatedAttributes:Add( oCAPICOMTimeStamp )
oCAPICOMSignedData := win_OleCreateObject( "CAPICOM.SignedData.1" )
oCAPICOMSignedData:Content := cDigestValue
// segundo parametro falso, apenas retona assinatura do texto, não inclui no texto
cSignature := oCAPICOMSignedData:Sign( oCAPICOMSigner, .F., nEncode )
RETURN cSignature
Código: Selecionar todos
PROCEDURE Main
LOCAL cXml, cDigestValue, cSignatureValue, cXml2, cPublicKey
cPublicKey := CapicomClass():PublicKey( CapicomCertificado( "CORDEIRO" ) )
cXml := MemoRead( "X.XML" )
cXml2 := cXml
cXml := XmlNode( cXml, "infNFe", .T. )
cDigestValue := CapicomClass():HashData( cXml )
cSignatureValue := CapicomClass():Sign( cDigestValue, , , @cPublicKey )
CapicomAssinaXml( @cXml2, "CORDEIRO" )
hb_MemoWrit( "d:\temp\assinado.xml", cXml2 )
? "DigestValue", cDigestValue
? "DigestValue", XmlNode( cXml2, "DigestValue" )
? cDigestValue == XmlNode( cXml2, "DigestValue" )
? cSignatureValue == XmlNode( cXml2, "SignatureValue" )
? cPublicKey == XmlNode( cXml2, "X509Certificate" )
Inkey(0)
RETURN
Código: Selecionar todos
hbmk2 test.prg \cdrom\fontes\integra\sefazclass\drafts\assinaturacapicom.prg -otest josequintas.hbc -gtwin
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/
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/
- sygecom
- Administrador

- Mensagens: 7131
- Registrado em: 21 Jul 2006 10:12
- Localização: Alvorada-RS
- Contato:
Assinar texto/arquivo com certificado digital pelo windows
Ze,
Tenho uma sugestão. Depois de usar o METODO OPEN() da CAPICOM.Store, seria bom fechar o mesmo com: oCapicom:close(), isso evita corromper o certificado A3 que fica gravado nos pendrive/cartão, para certificado A1, se acontecer é só instalar de novo.
https://msdn.microsoft.com/en-us/librar ... 2147217396
Tenho uma sugestão. Depois de usar o METODO OPEN() da CAPICOM.Store, seria bom fechar o mesmo com: oCapicom:close(), isso evita corromper o certificado A3 que fica gravado nos pendrive/cartão, para certificado A1, se acontecer é só instalar de novo.
Código: Selecionar todos
oCapicom:= win_OleCreateObject( "CAPICOM.Store" )
oCapicom:Open( CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY )
BEGIN SEQUENCE WITH { || __BreakBlock() }
oCertificate := oCapicom:Certificates:Select( "Selecione um certificado digital", "Algoritmo de Assinatura SHA256RSA" )
END SEQUENCE
oCapicom:close()https://msdn.microsoft.com/en-us/librar ... 2147217396
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
xHarbour.org + Hwgui + PostgreSql
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Assinar texto/arquivo com certificado digital pelo windows
Lembro de ter gerado erro no Close(), por isso deixei de usar.
Uso assim há anos e nunca tive problema.
Mas vou fazer novos testes.
Uso assim há anos e nunca tive problema.
Mas vou fazer novos testes.
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/
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/