The RSA encryption engine takes as input a public RSA key (X.509, certificate) and using PKCS1 padding scheme produces encrypted output. The ORA_RSA PL/SQL package expects the public keys to be supplied as values of type RAW.
A special caution that we have to take into account when performing RSA encryption is that the input data is limited to 245 bytes with a 2048 bit RSA key
In the examples below, you can see how to encrypt by using keys loaded from the server file system, hard coded inside the PL/SQL code, or by simply providing the public exponent and modulus of the key.
Table of contents
1. RSA encrypting with key loaded from a file
2. RSA encrypting with key in a LOB field
3. RSA encrypting with modulus and public exponent
1. RSA encrypting with key loaded from a file
PL/SQL code can load external files in variables of type BFILE. Keys loaded this way can be stored for subsequent use in special database tables. In order to access keys from the server file system we must create directory object pointing to their location, like:
CREATE DIRECTORY KEYS_DIR AS '/demo/schema/my_keys_folder';
In the code block below we are going to load the contents of a key file inside a BLOB field and pass it to the ORA_RSA.ENCRYPT method:
DECLARE public_key_file_handle BFILE; public_key BLOB; encrypted_data raw(32000); BEGIN -- initialize the public key BLOB storage DBMS_LOB.createtemporary(public_key, TRUE); -- load a key from the flesystem -- the direcory name must be created upfront with CREATE DIRECTORY -- for example: CREATE DIRECTORY KEYS_DIR AS '/demo/schema/my_keys_folder'; --public_key_file_handle := BFILENAME('KEYS_DIR', 'DidiSoftEood.crt'); -- Note: directory name must be Upper case public_key_file_handle := BFILENAME('KEYS_DIR', 'didisoft_public.der'); -- Note: directory name must be Upper case -- load the key into a BLOB DBMS_LOB.OPEN(public_key_file_handle, DBMS_LOB.LOB_READONLY); DBMS_LOB.LoadFromFile( DEST_LOB => public_key, SRC_LOB => public_key_file_handle, AMOUNT => DBMS_LOB.GETLENGTH(public_key_file_handle) ); DBMS_LOB.CLOSE(public_key_file_handle); -- RSA Encrypt encrypted_data := ORA_RSA.ENCRYPT(message => UTL_I18N.STRING_TO_RAW('Hello World', 'AL32UTF8'), public_key => DBMS_LOB.substr(public_key)); END; |
2. RSA encrypting with key in a LOB field
Another option is to have the keys hard coded inside PL/SQL procedures. This is suitable if we are going to use only one key.
In this case we need the key in PEM format (text based format) and as you can see from the example below we use a CLOB field for a placeholder:
DECLARE public_key CLOB := '-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCTlRzFkKRlk4kexec91kCCLyW FA7m2QD1Mc49jYK4qJoZ6MI4IiuNENlDzcYAat8JTITKQKdNfjq+kdppDnLTmeeU I4Jtlc06L1uDLji1hgeN315t6g3tOf0iHVdyt4dilcHDannCU0duU0TXhh6OK/HH HtwZ7lcxCo5NgzUDlwIDAQAB -----END PUBLIC KEY-----'; encrypted_data raw(32000); BEGIN -- RSA Encrypt encrypted_data := ORA_RSA.ENCRYPT(message => UTL_I18N.STRING_TO_RAW('Hello World', 'AL32UTF8'), public_key => UTL_RAW.CAST_TO_RAW(public_key)); END; |
3. RSA encrypting with modulus and exponent
RSA keys are nothing more than two big integer values called modulus and exponent. Although not common we may like to encrypt by just supplying those numbers. For that purpose the package provides a special function called ORA_RSA.ENCRYPT_WITH_MODULUS:
DECLARE public_key_modulus CLOB := 'c24e5473164291964e247b179cf7590208bc96140ee6d900f531ce3d8d82b8a89a19e8c238222b8d10d943cdc6006adf094c84ca40a74d7e3abe91da690e72d399e79423826d95cd3a2f5b832e38b586078ddf5e6dea0ded39fd221d5772b7876295c1c36a79c253476e5344d7861e8e2bf1c71edc19ee57310a8e4d83350397'; public_key_exponent CLOB := '10001'; encrypted_data raw(32000); BEGIN -- RSA Encrypt encrypted_data := ORA_RSA.ENCRYPT_WITH_MODULUS(message => UTL_I18N.STRING_TO_RAW('Hello World', 'AL32UTF8'), public_key_modulus => DBMS_LOB.substr(public_key_modulus), public_key_exponent => DBMS_LOB.substr(public_key_exponent)); END; |
Summary
This article demonstrated RSA encryption with the DidiSoft ORA_RSA PL/SQL package.