What it translates to in Harbour - AES 256 (AES/ECB/PKCS7Padding)

712 views
Skip to first unread message

Pritpal Bedi

unread,
Jan 23, 2022, 5:19:17 PM1/23/22
to Harbour Users
Hi Everybody

Can you explain which functions of Harbour can encrypt a string per above protocol ?

I suppose hb_sha256() is the way to go ( as imagined from AES 256 notation ) but I may be wrong. First timer to play with India's E-Invoicing so need to secure this info.


Thanks in advance.


Pritpal Bedi
a student of software analysis & concepts

Jiju Chackungal

unread,
Jan 24, 2022, 6:59:32 PM1/24/22
to Harbour Users
Hello Pritpal,
First of all, let me thank you for being the 'virtual' Guide to me (and I believe for 100s of developers like me) in resurrecting all my Clipper Applications! with your example codes + contributions and HBIDE! 
Let me also thank all the Great people who are contributing in their capacities to maintain and progress the Harbour Platform (the list is long)!

Now coming to your question about AES 256, for all my encryption requirements, I have been using OpenSSL utility with hb_Processrun(....) and wished to use something that was native to Harbour instead of depending on any external utility.

I use:
 nProcessError := hb_Processrun(cOpenSSLPath+"openssl smime -encrypt -binary -aes-256-cbc -in "+cExpFile + " -out "+ xExpFile + " -outform DER " + keyfile,@cOutErr,@cOutErr,,.T.)
Input file: <cExpFile>
Output file: <xExpFile>
Key: <keyfile>

Works perfect and needs OpenSSL.exe, libeay32.dll and ssleay32.dll.
I searched a bit online and didn't find anything helpful.

Now with your post/question, I am very excited and hopeful!

I will eagerly wait for the replies/inputs from the Harbour Community to your question/post.

Pritpal Bedi

unread,
Jan 25, 2022, 10:14:29 PM1/25/22
to Harbour Users
Thanks for replying.

I believe native implementation will be the best but in case it won't be possible, I will adopt your code.


Pritpal Bedi
a student of software analysis & concepts

Marek Olszewski "MOL"

unread,
Jul 11, 2024, 6:58:58 AM7/11/24
to Harbour Users
Hi Pritpal!
Can I ask if  you implemented decoding procedure?

jijucha...@gmail.com

unread,
Jul 18, 2024, 5:07:10 AM7/18/24
to Harbour Users
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,

bedipr...@gmail.com

unread,
Jul 18, 2024, 1:56:13 PM7/18/24
to Harbour Users
Hi 

Seems a native solution is here. Can you provide a .prg with a small functional example? It will be great help to community.

Thanks 
Pritpal Bedi
a student of software analysis and concepts

jijucha...@gmail.com

unread,
Jul 19, 2024, 4:46:35 AM7/19/24
to Harbour Users
Hi Pritpal,
I am travelling overseas and caught up with multiple things.
I will try to write a test .PRG using these functions and I will share as soon as I get a chance.

Thanks,

Marek Olszewski "MOL"

unread,
Jul 19, 2024, 6:51:18 AM7/19/24
to Harbour Users
Add Initial Vector to your sample, please...

diego...@gmail.com

unread,
Jul 19, 2024, 12:40:43 PM7/19/24
to Harbour Users
Hi, Here are the functions and an example. 

This files must be with the binary...

Windows:
libcrypto-1_1-x64.dll
libssl-1_1-x64.dll

Linux:
libcrypto.so.1.1
libssl.so.1.1

Diego.

EVP_CIPHER.prg

bedipr...@gmail.com

unread,
Jul 20, 2024, 4:06:33 PM7/20/24
to Harbour Users
Thanks Diego

It helped. Attached is your source but with some formatting and fixing warnings.


Pritpal Bedi
a student of software analysis & concepts

EVP_CIPHER.prg

Marek Olszewski "MOL"

unread,
Jul 21, 2024, 6:07:53 AM7/21/24
to Harbour Users
Is it possible to work without ssleay32.dll and libeay32.dll?

diego...@gmail.com

unread,
Jul 21, 2024, 11:44:45 AM7/21/24
to Harbour Users

Yes, sure.

1) You should have OpenSSL libraries built with support for static linking. This is not usually found. If you don't have them, you need to download the OpenSSL source code and build it with the "no-shared" option. Attached below...
2) Compile your project with....
Set HB_STATIC_OPENSSL=yes. 
Use hbssl.hbc and link the static versions of libcrypto and libssl.

Openssl static libs
Compiled with MSVC64 and Harbour 3.2.0dev (r2405310955) OpenSSL ver.1.1.1w

Diego.




Reply all
Reply to author
Forward
0 new messages