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)