Gents,
I have implemented the decoding procedure using the same hb_ProcessRun(....) function and externally installed OpenSSL.exe,
libeay32.dll and ssleay32.dll. Works perfectly in the production environment.
For encrypting strings, I have written a few functions that is using the harbour contrib implementations.
For example, this function encrypts any string using any of the protocols.
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Some info that I have compiled for my ready reference.
Electronic codebook (ECB) / Cipher block chaining (CBC) / Propagating CBC (PCBC) / Cipher feedback (CFB) / Output feedback (OFB) / Counter (CTR)
"AES-192-OFB" [Cipher 65] [BlockSize 1] Works perfectly with decryption. Return string size is the same as the defined/declared string size space(64) or space(32). [for both encrypted and decrypted string]
"AES-256-CBC" [Cipher 67] [BlockSize 16] Leaves junk at the tail if decrypted in the encryption function call. Decrypt function fails to decrypt. Return size is > the defined size. Works if the trailing space is removed from the input string
"AES-128-CBC" [Cipher 53] [BlockSize 16] Works. Enc String is 48 and Dec String is Original size
"AES-128-CFB" [Cipher 56] [BlockSize 16] Works. Enc String is 32 and Dec String is Original size
"AES-128-ECB" [Cipher 52] [BlockSize 16] Works. Enc String is 48 and Dec String is Original size [Avoid using ECB- not recommended]
"AES-128-OFB" [Cipher 58] [BlockSize 16] Works. Enc String is 32 and Dec String is Original size
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
<cUEString> unencrypted string to be encrypted
<cKey> your key for the encryption
<cAlgorithm> Encryption method to use. HB_EVP_CIPHER_AES_256_ECB etc.... etc...
FUNCTION StrEncrypt(cUEString, cKey, cAlgorithm)
LOCAL ctx, result := "", encrypted :="", decrypted :="" ,nBlockSz :=0, nCipher := 0
if (cUEString == NIL)
return result
endif
// Assign default values to the critical parameters, just in case they are not assigned a valid value
cKey := Defv(cKey,"GetFileAttributesExWindows") // for AES-192 and AES-256, the Key length has to be sufficient enough for the additional rounds (12 and 14..)
cAlgorithm := Defv(cAlgorithm, JC_EVP_CIPHER_AES_128_CBC )
if (len(cKey) < 20)
return result
endif
SSL_init()
OpenSSL_add_all_ciphers()
ctx := HB_EVP_CIPHER_ctx_create()
EVP_CIPHER_CTX_init( ctx )
if ! Empty( ctx )
EVP_EncryptInit( ctx, cAlgorithm , cKey ) // init ctx with algorithm and key
nCipher := EVP_CIPHER_CTX_cipher( ctx ) // select the cipher/algorithm
nBlockSz := EVP_CIPHER_block_size( EVP_CIPHER_CTX_cipher( ctx ) ) //set the blocksize based on the cipher
encrypted := ""
result := ""
EVP_EncryptUpdate( ctx, @result, cUEString)
encrypted += result
EVP_EncryptFinal( ctx, @result )
encrypted += result
ctx := NIL
EVP_cleanup()
endif
RETURN encrypted
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
<cEncString> encrypted string to be decrypted
<cKey> your key for the encryption
<cAlgorithm> Encryption method to used to encrypt <cEncString>. HB_EVP_CIPHER_AES_256_ECB etc.... etc...
Note: <cAlgorithm> and <cKey> should be identical for Encrpytion and Decryption of a give string.....
FUNCTION StrDecrypt(cEncString, cKey, cAlgorithm)
LOCAL ctx, result := "", decrypted :="", nBlockSz := 0, nCipher := 0
if (cEncString == NIL)
return result
endif
// Assign default values to the critical parameters, just in case they are not assigned a valid value
cKey := Defv(cKey,"SomeRandomKey4DefaultValue") // for AES-192 and AES-256, the Key length has to be sufficient enough for the additional rounds (12 and 14..)
cAlgorithm := Defv(cAlgorithm, JC_EVP_CIPHER_AES_128_CBC )
if (len(cKey) < 20)
return result
endif
// SSL_Init and OpenSSL_add_all_ciphers() not required to be called for decryption....!!!
SSL_init()
OpenSSL_add_all_ciphers()
ctx := HB_EVP_CIPHER_ctx_create()
EVP_CIPHER_CTX_init( ctx )
if ! Empty( ctx )
EVP_DecryptInit( ctx, cAlgorithm , cKey )
nCipher := EVP_CIPHER_CTX_cipher( ctx ) // Set the Cipher / Algorithm
nBlockSz:= EVP_CIPHER_block_size( EVP_CIPHER_CTX_cipher( ctx ) ) // Set Blocksize - based on the Algorithm
decrypted := ""
result := ""
EVP_DecryptUpdate( ctx, @result, cEncString )
decrypted += result
EVP_DecryptFinal( ctx, @result )
decrypted += result
ctx := NIL
EVP_cleanup()
endif
RETURN decrypted
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
These functions are copied from my working source code and will work for anyone as long as you use:
#require "hbssl"
and have all the EVP_CIPHERS..... defined in the header. For my implementation, I have add "JC_" to the standard defines in contrib/hbssl/
hbssl.ch
Please feel free to ask me if you need any additional information.
Thanks,