DBMS_CRYPTO provides an interface to encrypt and decrypt stored
data, and can be used in conjunction with PL/SQL programs running network
communications. It provides support for several industry-standard encryption
and hashing algorithms, including the Advanced Encryption Standard (AES)
encryption algorithm. AES has been approved by the National Institute of
Standards and Technology (NIST) to replace the Data Encryption Standard (DES).
DBMS_CRYPTO
contains basic cryptographic functions and procedures. To use this package
correctly and securely, a general level of security expertise is assumed.
The DBMS_CRYPTO
package enables encryption and decryption for common Oracle datatypes,
including RAW
and large
objects (LOB
s), such as
images and sound. Specifically, it supports BLOB
s
and CLOB
s. In addition,
it provides Globalization Support for encrypting data across different database
character sets.
The
following cryptographic algorithms are supported:
·
Data Encryption Standard (DES), Triple DES (3DES, 2-key and 3-key)
·
Advanced Encryption Standard (AES)
·
MD5, MD4, and SHA-1 cryptographic hashes
·
MD5 and SHA-1 Message Authentication Code (MAC)
Block
cipher modifiers are also provided with DBMS_CRYPTO
.
You can choose from several padding options, including PKCS (Public Key
Cryptographic Standard) #5, and from four block cipher chaining modes,
including Cipher Block Chaining (CBC).
Package Feature
|
DBMS_CRYPTO
|
DBMS_OBFUSCATION_TOOLKIT
|
Cryptographic
algorithms
|
DES,
3DES, AES, RC4, 3DES_2KEY
|
DES,
3DES
|
Padding
forms
|
PKCS5,
zeroes
|
none
supported
|
Block
cipher chaining modes
|
CBC,
CFB, ECB, OFB
|
CBC
|
Cryptographic
hash algorithms
|
MD5,
SHA-1, MD4
|
MD5
|
Keyed
hash (MAC) algorithms
|
HMAC_MD5,
HMAC_SH1
|
none
supported
|
Cryptographic
pseudo-random number generator
|
RAW,
NUMBER, BINARY_INTEGER
|
RAW,
VARCHAR2
|
Database
types
|
RAW,
CLOB, BLOB
|
RAW,
VARCHAR2
|
DBMS_CRYPTO
is
intended to replace the DBMS_OBFUSCATION_TOOLKIT
,
providing greater ease of use and support for a range of algorithms to
accommodate new and existing systems. Specifically, 3DES_2KEY
and MD4 are provided
for backward compatibility. It is not recommended that you use these algorithms
because they do not provide the same level of security as provided by 3DES,
AES, MD5, or SHA-1.
Parameters for the DBMS_CRYPTO
subprograms use these datatypes:
Type
|
Description
|
BLOB
|
A source or destination
binary LOB
|
CLOB
|
A source or destination
character LOB (excluding NCLOB)
|
PLS_INTEGER
|
Specifies a
cryptographic algorithm type (used with BLOB, CLOB, and RAW datatypes)
|
RAW
|
A source or destination
RAW buffer
|
The following cryptographic algorithms, modifiers, and cipher
suites are predefined in this package.
Name
|
Description
|
HASH_MD4
|
Produces a 128-bit hash,
or message digest of the input message
|
HASH_MD5
|
Also produces a 128-bit
hash, but is more complex than MD4
|
HASH_SH1
|
Secure Hash Algorithm
(SHA). Produces a 160-bit hash.
|
DBMS_CRYPTO Encryption Algorithms:
Name
|
Description
|
ENCRYPT_DES
|
Data Encryption
Standard. Block cipher. Uses key length of 56 bits.
|
ENCRYPT_3DES_2KEY
|
Data Encryption
Standard. Block cipher. Operates on a block 3 times with 2 keys. Effective
key length of 112 bits.
|
ENCRYPT_3DES
|
Data Encryption
Standard. Block cipher. Operates on a block 3 times.
|
ENCRYPT_AES128
|
Advanced Encryption
Standard. Block cipher. Uses 128-bit key size.
|
ENCRYPT_AES192
|
Advanced Encryption
Standard. Block cipher. Uses 192-bit key size.
|
ENCRYPT_AES256
|
Advanced Encryption
Standard. Block cipher. Uses 256-bit key size.
|
ENCRYPT_RC4
|
Stream cipher. Uses a
secret, randomly generated key unique to each session.
|
When
to Use Encrypt and Decrypt Procedures or Functions
This
package includes both ENCRYPT and DECRYPT procedures and functions. The
procedures are used to encrypt or decrypt LOB datatypes (overloaded for CLOB
and BLOB datatypes). In contrast, the ENCRYPT and DECRYPT functions are used to
encrypt and decrypt RAW datatypes. Data of type VARCHAR2 must be converted to RAW
before you can use DBMS_CRYPTO functions to encrypt it.
When to Use Hash or Message Authentication Code (MAC) Functions
This package includes two different types of one-way hash
functions: the HASH
function and the MAC
function. Hash functions operate on an arbitrary-length input message, and
return a fixed-length hash value. One-way hash functions work in one direction
only. It is easy to compute a hash value from an input message, but it is
extremely difficult to generate an input message that hashes to a particular
value. Note that hash values should be at least 128 bits in length to be
considered secure.
You can use hash values to verify whether data has been altered.
For example, before storing data, Laurel runs DBMS_CRYPTO.HASH
against the stored data to create a hash value. When she retrieves the stored
data at a later date, she can again run the hash function against it, using the
same algorithm. If the second hash value is identical to the first one, then
the data has not been altered. Hash values are similar to "file
fingerprints" and are used to ensure data integrity.
The HASH
function included with DBMS_CRYPTO
,
is a one-way hash function that you can use to generate a hash value from
either RAW
or LOB
data. The MAC
function is also a one-way hash function, but with the addition of a secret
key. It works the same way as the DBMS_CRYPTO.HASH
function, except only someone with the key can verify the hash value.
MACs can be used to authenticate files between users. They can
also be used by a single user to determine if her files have been altered,
perhaps by a virus. A user could compute the MAC of his files and store that
value in a table. If the user did not use a MAC function, then the virus could
compute the new hash value after infection and replace the table entry. A virus
cannot do that with a MAC because the virus does not know the key.
About Generating and Storing Encryption Keys
The DBMS_CRYPTO
package can generate random material for encryption keys, but it does not
provide a mechanism for maintaining them. Application developers must take care
to ensure that the encryption keys used with this package are securely
generated and stored. Also note that the encryption and decryption operations
performed by DBMS_CRYPTO
occur on the server, not on the client. Consequently, if the key is sent over
the connection between the client and the server, the connection must be
protected by using network encryption. Otherwise, the key is vulnerable to
capture over the wire.
Although DBMS_CRYPTO
cannot generate keys on its own, it does provide tools you can use to aid in
key generation. For example, you can use the RANDOMBYTES
function to generate random material for keys. (Calls to the RANDOMBYTES
function behave like calls to the DESGETKEY
and DES3GETKEY
functions of the DBMS_OBFUSCATION_TOOLKIT
package.)
When generating encryption keys for DES, it is important to
remember that some numbers are considered weak and semi-weak keys. Keys are
considered weak or semi-weak when the pattern of the algorithm combines with the
pattern of the initial key value to produce ciphertext that is more susceptible
to cryptanalysis. To avoid this, filter out the known weak DES keys. Lists of
the known weak and semi-weak DES keys are available on several public Internet
sites.
Conversion Rules
To
convert VARCHAR2
to RAW
, use the UTL_I18N.STRING_TO_RAW
function to perform the following steps:
1. Convert
VARCHAR2
in the
current database character set to VARCHAR2
in the AL32UTF8 database character.
2. Convert
VARCHAR2
in the
AL32UTF8 database character set to RAW
.
Syntax
example: UTL_I18N.STRING_TO_RAW (string,
'AL32UTF8');
To
convert RAW
to VARCHAR2
, use the UTL_I18N.RAW_TO_CHAR
function to perform the following steps:
1. Convert
RAW
to VARCHAR2
in the AL32UTF8 database character set.
2. Convert
VARCHAR2
in the
AL32UTF8 database character set to VARCHAR2
in the database character set you wish to use.
Syntax
example: UTL_I18N.RAW_TO_CHAR (data, 'AL32UTF8');
Example:
The following listing shows PL/SQL block encrypting and decrypting pre-defined
'input_string
' using
256-bit AES algorithm with Cipher Block Chaining and PKCS#5 compliant padding.
DECLARE
input_string VARCHAR2 (200):= 'Secret Message';
output_string VARCHAR2 (200);
encrypted_raw RAW (2000); -- stores encrypted binary text
decrypted_raw RAW (2000); -- stores decrypted binary text
num_key_bytes NUMBER := 256/8; -- key length 256 bits (32 bytes)
key_bytes_raw RAW (32); -- stores 256-bit encryption key
encryption_type PLS_INTEGER := -- total encryption type
DBMS_CRYPTO.ENCRYPT_AES256
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
BEGIN
DBMS_OUTPUT.PUT_LINE ( 'Original string: ' || input_string);
key_bytes_raw := DBMS_CRYPTO.RANDOMBYTES (num_key_bytes);
encrypted_raw := DBMS_CRYPTO.ENCRYPT
(
src => UTL_I18N.STRING_TO_RAW (input_string, 'AL32UTF8'),
typ => encryption_type,
key => key_bytes_raw
);
-- The encrypted value "encrypted_raw" can be used here
decrypted_raw := DBMS_CRYPTO.DECRYPT
(
src => encrypted_raw,
typ => encryption_type,
key => key_bytes_raw
);
output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');
DBMS_OUTPUT.PUT_LINE ('Decrypted string: ' || output_string);
END;