9 79 ENCRYPT

LANSA Technical

9.79 ENCRYPT

Þ Note: Built-In Function Rules.

Encrypt a text string.

A companion Built-in Function, 9.35 DECRYPT, is used to decode the encrypted text string.

Warning: From this version (LANSA V11 SP4) onward, a blank key won't be used to encrypt, a generated key will be used instead if the key argument is passed with all blanks. In versions prior to V11 SP4, encrypt will have a key of all spaces.

LANSA for i

YES

Visual LANSA for Windows

YES

Visual LANSA for Linux

YES

 

 

Arguments

No

Type

Req/ Opt

Description

Min Len

Max Len

Min Dec

Max Dec

1

u

Req

Text to be encrypted

8

Unlimited

 

 

2

N

Req

Length of text to be encrypted

The value for this length argument must be a multiple of 8.

The value provided for this argument must not be greater than the length of Argument 1 (text to be encrypted).

1

11

0

0

3

u

Opt

Key to be used for encryption

If a key is not provided for the encryption, a key will be generated and returned.

The key used for encryption must be saved and provided to the DECRYPT Built-In Function.

The current encryption cipher uses 16 bytes/128 bits key. The last 16 bytes are reserved for future use.

If a Unicode field type is used it is converted to UTF-8 and truncated to 32 bytes. If the key is not provided, and if return value 3 is a Unicode field type, then a Unicode key is generated. This key is converted to UTF-8 and truncated to 32 bytes. Alternatively, a key may be automatically generated using a Unicode field for the key, but setting it to an empty string.

16

32

 

 

4

A

Opt

Encrypted text stored in HEX.

YES= return encrypted text in HEX format.
NO= Return encrypted text in binary format.

Default is NO.

2

3

 

 

 

 

Return Values

No

Type

Req/ Opt

Description

Min Len

Max Len

Min Dec

Max Dec

1

A

Req

Returned encrypted text

8

Unlimited

 

 

2

A

Opt

Return code

OK = action completed

ER = error occurred

2

2

 

 

3

u

Opt

Key used for encryption when no key argument provided

16

32

 

 

 

 

Technical Notes

  • Cipher block encryption algorithms always encrypt and decrypt blocks of 8 characters. Therefore the actual value you encrypt must have a length that is a multiple of 8.
  • The encrypted data returned by the encryption algorithm is binary data and can contain any value. As such, using it or passing it through environments where it may be subject to code page conversion (eg: database managers, communications links, etc) or where special characters like CR, LF or binary zero may cause issues (eg: HTML or XML documents, string processing, stream file processing, etc) may prove to be problematic. As such it is recommended that encrypted data is physically stored in hexadecimal format.
  • Unicode fields are converted to UTF-8 before encryption. This allows a Unicode field to be encrypted on one platform and decrypted on another. It also means that the encryption length (argument 2) can be up to 3 times the length of the text to be encrypted (argument 1). And then if the result is stored in hex it's further doubled in size. So if you have a 500 character NVarchar then the encrypted length should be 1500 and the size of the returned encrypted text should be 3000. If you do not have the lengths in this ratio then data may be lost.

Examples

Following are two RDML subroutines that demonstrate a generic encryption technique for any information up to 16 characters in length.  

For example EXECUTE ENCRYPT (#KEY #PROD_NUM #PROD_ENC) might encrypt #PROD_NUM (char 10) to produce encrypted #PROD_ENC (char 32).

Note that even though the subroutine parameter #PROD_NUM is a char 10 field, the resulting encryption field #PROD_ENC is char 32.

This is because the initial binary encryption requires an input that is a multiple of 8 (ie: char 10 #PROD_NUM is padded with blanks to be 16 bytes long by the subroutine execution) and it produces a hexadecimal representation of the encrypted binary data, which is therefore 32 bytes long. 

All 32 bytes of #PROD_ENC need to be stored for successful decryption to occur later. 

To decrypt these values you would code EXECUTE DECRYPT (#KEY #PROD_ENC #PROD_NUM).

Here the 32 byte hexadecimal value is first converted to binary, decrypted and then returned as a char 16.

The subroutine finally returns the decrypted value right truncated into #PROD_NUM as a char 10.

ENCRYPT a value with a supplied key and return a 32 byte encrypted value in hex

********** ======================================================= 
********** Sample routine to Encrypt a passed in value (up to 16   
********** bytes in length) with a supplied key and return a       
********** 32 byte encrypted value in hex (suitable for storing in 
********** database, etc)                                         
********** ======================================================= 
SUBROUTINE NAME(ENCRYPT) PARMS((#KEY16 *RECEIVED) (#VAL16 *RECEIVED) (#HEX32 *RETURNED))
DEFINE     FIELD(#KEY16) TYPE(*CHAR) LENGTH(16) DESC('Encryption key supplied')
DEFINE     FIELD(#VAL16) TYPE(*CHAR) LENGTH(16) DESC('Value to be encrypted')
DEFINE     FIELD(#HEX32) TYPE(*CHAR) LENGTH(32) DESC('Encrypted value in Hex')
DEFINE     FIELD(#LEN) TYPE(*DEC) LENGTH(5) DECIMALS(0)           
CHANGE     #LEN 16                                                
********** Use ENCRYPT BIF to encrypt #VAL16 of length #LEN using 
********** #KEY16 to return encrypted value in #HEX32             
********** The encrypted value is converted into HEX resulting in 
********** a 32 byte value.
USE        BUILTIN(ENCRYPT) WITH_ARGS(#VAL16 #LEN #KEY16 YES) TO_GET(#HEX32)
ENDROUTINE                                                        
********** =======================================================
 

DECRYPT a Hex value using the supplied key and return the unencrypted value

********** ======================================================= 
********** Sample routine to Decrypt a passed in Hex value         
********** using the supplied key and return the unencrypted       
********** value.                                                  
********** ======================================================= 
SUBROUTINE DECRYPT ((#DKEY16 *Received)(#DHEX32 *Received) (#DVAL16 *Returned))
********** Key to be used for the decryption. This must be the     
********** same key that was used for the encryption.              
DEFINE     #DKEY16 *char 16                                        
DEFINE     FIELD(#DHEX32) TYPE(*CHAR) LENGTH(32) DESC('Encrypted value in hex')
DEFINE     FIELD(#DVAL16) TYPE(*CHAR) LENGTH(16) DESC('Decrypted value returned') 
DEFINE     FIELD(#DLEN) TYPE(*DEC) LENGTH(5) DECIMALS(0)            
CHANGE     FIELD(#DLEN) TO(16)                                      
**********
**********
********** Use DECRYPT BIF to decrypt character #HEX32 of length   
********** #DLEN using #DKEY16 to return decrypted value,#DVAL16    
**********                                                          
USE        BUILTIN(DECRYPT) WITH_ARGS(#HEX32 #DLEN #DKEY16 YES) TO_GET(#DVAL16)
ENDROUTINE                                                          
 

ENCRYPT a password and then DECRYPT

DEFINE     FIELD(#PASSWORD) TYPE(*CHAR) LENGTH(10)                 
DEFINE     FIELD(#TEXT) TYPE(*CHAR) LENGTH(16)                     
DEFINE     FIELD(#LENGTH) TYPE(*DEC) LENGTH(11) DECIMALS(0)        
DEFINE     FIELD(#KEY) TYPE(*CHAR) LENGTH(16)                      
DEFINE     FIELD(#RETCODE) TYPE(*CHAR) LENGTH(2)                   
DEFINE     FIELD(#ENCRYPTED) TYPE(*CHAR) LENGTH(16)                
DEFINE     FIELD(#DECRYPTED) TYPE(*CHAR) LENGTH(16)                
**********
********** Encrypt password with key                               
CHANGE     #TEXT #PASSWORD                                         
CHANGE     #LENGTH 16                                              
CHANGE     #KEY 'AXG12345lj0gtUMX'                                 
USE        BUILTIN(ENCRYPT) WITH_ARGS(#TEXT #LENGTH #KEY) TO_GET(#ENCRYPTED #RETCODE)
**********
********** Decrypt password with same key as provided for encryption
CHANGE     #LENGTH 16                                              
USE        BUILTIN(DECRYPT) WITH_ARGS(#ENCRYPTED #LENGTH #KEY) TO_GET(#DECRYPTED #RETCODE)
**********