Appendix B: DATA_CRYPTO Package

The DBMS_CRYPTO package provides a comprehensive set of procedures and functions that will allow you to encrypt and decrypt data in the confines of the database. For most of the basic data types, such as VARCHAR2, dates, and numbers, you’ll have to convert the data to a RAW prior to invoking the DBMS_CRYPTO package. CLOB and BLOB encryption is natively supported but only through procedures. Also, the encryption key used must be a RAW and has to be the appropriate size for the encryption algorithm you’ll be using.

These are facts and not criticisms. The DBMS_CRYPTO package is implemented effectively and these requirements are, at most, inconvenient. Chapter 13 discusses relevant issues, such as storing encrypted data and the importance of the encryption key, and gives many examples of how to encrypt and decrypt data.

The DATA_CRYPTO package provided here is meant to serve two purposes. First, it simplifies the encryption and decryption calls by performing the data-type castings and algorithmic-based key sizing. The encryption and decryption programs are administered as functions so they can

be called within SQL statements. See Chapter 13 for examples.

The second purpose of DATA_CRYPTO is to serve as a template for implementing your specific encryption/decryption code. The code illustrates how to invoke DBMS_CRYPTO, and it implicitly offers suggestions for helper functions that you might administer. This should allow you to more easily encrypt and decrypt data that is important in supporting the wide-scale use of stored database encryption.

CREATE OR REPLACE PACKAGE data_crypto   AS   /* DATA_CRYPTO    * * This package is a utility that invokes procedures and functions in    * the default DBMS_CRYPTO package. This    * package provides functions for strings, numbers, * dates, CLOB, and BLOBs. Helper functions are also    * provided. Default encryption is AES 128-bit. Default    * hash is SHA. * */     ---------------------------------------------------------   --                  Encryption                         --   ---------------------------------------------------------       -- Returns integer value for encryption algorithm     -- The DES algorithm. Requires 8-byte key.   FUNCTION des       RETURN PLS_INTEGER; -- Triple DES using 3 distinct keys     FUNCTION des3       RETURN PLS_INTEGER;  -- Triple DES using 2 keys   FUNCTION des32      RETURN PLS_INTEGER; -- AES at 128-bit. Requires 16-byte key     FUNCTION aes       RETURN PLS_INTEGER; -- Stronger AES with at 192-bit key length (24-bytes)   FUNCTION aes192      RETURN PLS_INTEGER; -- Strongest AES at 256-bit key length (32-bytes)   FUNCTION aes256       RETURN PLS_INTEGER; -- Stream Cipher Algorithms     -- Key size is variable.   FUNCTION rc4       RETURN PLS_INTEGER; -- Set encryption algorithm     -- Stores value in global package variable     PROCEDURE set_algorithm (p_enc_algorithm IN PLS_INTEGER); -- return character representation of currently set algorithm     FUNCTION get_algorithm      RETURN VARCHAR2; -- Stores key as a global package variable     -- Key is sized based on algorithm passed or globally     -- defined algorithm     PROCEDURE setkey (     p_key            IN  VARCHAR2,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL); -- return RAW key of appropriate size based on algorithm     -- if algorithm is null, the global algorithm will be used.   FUNCTION getkey (     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW; -- encrypts VARCHAR2 and return VARCHAR2 data     -- calls encrypt with utl_raw casting      FUNCTION encrypt (     p_data           IN  VARCHAR2,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2; -- decrypts VARCHAR2 and return VARCHAR2 data   FUNCTION decrypt (     p_data           IN  VARCHAR2,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2; -- Accept string data and return RAW output     -- RAW output is not interpreted by database     -- and is therefore more suitable for storage      FUNCTION encrypt_char (     p_data           IN  VARCHAR2,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW; -- Accept RAW data and return as VARCHAR2     -- This is the complimentary function for encrypt_char      FUNCTION decrypt_char (     p_data           IN  RAW,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2; -- encrypts number and return raw data      FUNCTION encrypt_number (     p_data           IN  NUMBER,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW; -- decrypts raw and returns number data      FUNCTION decrypt_number (     p_data           IN  RAW,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN NUMBER; -- encrypts date and return raw data      FUNCTION encrypt_date (     p_data           IN  DATE,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW; -- decrypts raw and returns data as date     FUNCTION decrypt_date (     p_data           IN  RAW,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN DATE; -- encrypts a CLOB and return value as CLOB -- done as function for performing SQL updates     FUNCTION encrypt (     p_data           IN  CLOB,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN CLOB; -- decrypts a CLOB and return value as CLOB     -- done as function for performing SQL updates    FUNCTION decrypt (     p_data           IN  CLOB,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN CLOB; -- encrypts a BLOB and return value as BLOB     -- done as function for performing SQL updates     FUNCTION encrypt (     p_data           IN  BLOB,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN BLOB; -- decrypts a BLOB and return value as BLOB     -- done as function for performing SQL updates     FUNCTION decrypt (     p_data           IN  BLOB,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN BLOB; ---------------------------------------------------------   --                     HASHING                         --   ---------------------------------------------------------        -- returns integer value for hashing algorithm    FUNCTION md4      RETURN PLS_INTEGER;   FUNCTION md5      RETURN PLS_INTEGER;   FUNCTION sha      RETURN PLS_INTEGER;   -- sets global hashing algorithm    PROCEDURE set_hash_algorithm (       p_hash_algorithm  IN  PLS_INTEGER);   -- return global hashing algorithm as string    FUNCTION get_hash_algorithm        RETURN VARCHAR2;   -- Computes hash and return value as RAW       -- Uses p_hash_algorithm if passed, else       -- uses the global variable     FUNCTION hash2raw (     p_data            IN  VARCHAR2,     p_hash_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW;   -- Computes hash and return value as VARCHAR2     -- Uses p_hash_algorithm if passed, else      -- uses the global variable    FUNCTION HASH (     p_data            IN  VARCHAR2,     p_hash_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2; ---------------------------------------------------------     --       Hashed Message Authentication Codes           --   ---------------------------------------------------------      -- returns integer value for hashing algorithm    FUNCTION hmac_md5          RETURN PLS_INTEGER;   FUNCTION hmac_sha        RETURN PLS_INTEGER;   -- returns string value for current HMAC algorithm     FUNCTION get_hmac_algorithm         RETURN VARCHAR2;   -- Sets global HMAC algorithm to p_hash_algorithm       PROCEDURE set_hmac_algorithm (     p_hash_algorithm  IN  PLS_INTEGER);   -- Computes hashed message authentication code.   -- Returns value as RAW     -- Uses p_hash_algorithm if passed, else     -- uses the global hmac variable     FUNCTION mac2raw (     p_data            IN  VARCHAR2,     p_key             IN  VARCHAR2 DEFAULT NULL,     p_hash_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW;   -- Computes hashed message authentication code.   -- Returns value as VARCHAR2     -- Uses p_hash_algorithm if passed, else   -- uses the global hmac variable     FUNCTION mac (     p_data            IN  VARCHAR2,     p_key             IN  VARCHAR2 DEFAULT NULL,     p_hash_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2; END; /     CREATE OR REPLACE PACKAGE BODY data_crypto   AS   ---------------------------------------------------------   --   Integer values for encryption algorithms   --   Values are sum of base encryption algorithm, --   the block modifier, and the padding scheme   ---------------------------------------------------------        -- 56-bit DES     g_des       CONSTANT PLS_INTEGER       :=   dbms_crypto.encrypt_des           + dbms_crypto.chain_cbc           + dbms_crypto.pad_pkcs5;  -- Triple DES using 3 distinct keys      g_des3      CONSTANT PLS_INTEGER       :=   dbms_crypto.encrypt_3des_2key           + dbms_crypto.chain_cbc           + dbms_crypto.pad_pkcs5;  -- Triple DES using 2 keys    g_des32     CONSTANT PLS_INTEGER       :=   dbms_crypto.encrypt_3des           + dbms_crypto.chain_cbc           + dbms_crypto.pad_pkcs5;   -- AES at 128-bit. Requires 16-byte key     g_aes       CONSTANT PLS_INTEGER        :=   dbms_crypto.encrypt_aes           + dbms_crypto.chain_cbc           + dbms_crypto.pad_pkcs5;   -- Stronger AES with at 192-bit key length (24-bytes)   g_aes192    CONSTANT PLS_INTEGER         :=   dbms_crypto.encrypt_aes192         + dbms_crypto.chain_cbc           + dbms_crypto.pad_pkcs5;   -- Strongest AES at 256-bit key length (32-bytes)   g_aes256    CONSTANT PLS_INTEGER         :=   dbms_crypto.encrypt_aes256          + dbms_crypto.chain_cbc           + dbms_crypto.pad_pkcs5;   -- Stream Cipher Algorithms   -- Key size is variable.   g_rc4       CONSTANT PLS_INTEGER                                      := dbms_crypto.encrypt_rc4;   -- define the default encryption algorithm     -- modify this value to change your defaults     g_enc_algorithm      PLS_INTEGER      := g_aes;   -- create a global variable for holding key     -- RC4 has no key size limit      g_key                VARCHAR2 (32767); ---------------------------------------------------------   --                 HASHING   --   Integer values for hashing and HMAC algorithms   ---------------------------------------------------------     -- Hash Algorithms   g_md4       CONSTANT PLS_INTEGER   := dbms_crypto.hash_md4;   g_md5       CONSTANT PLS_INTEGER   := dbms_crypto.hash_md5;   g_sha       CONSTANT PLS_INTEGER   := dbms_crypto.hash_sh1;   -- globally defined (default) hashing algorithm       g_hash_algorithm     PLS_INTEGER      := g_sha;   -- MAC Functions     g_hmac_md5  CONSTANT PLS_INTEGER   := dbms_crypto.hmac_md5;   g_hmac_sha  CONSTANT PLS_INTEGER   := dbms_crypto.hmac_sh1;   -- globally defined (default) hashing algorithm     g_hmac_algorithm     PLS_INTEGER      := g_hmac_sha; ---------------------------------------------------------   --   Functions for returning the integer value   --   of respective algorithms   ---------------------------------------------------------      FUNCTION des       RETURN PLS_INTEGER     AS    BEGIN       RETURN g_des;  END; ---------------------------------------------------------    FUNCTION des3       RETURN PLS_INTEGER     AS     BEGIN       RETURN g_des3;  END; ---------------------------------------------------------     FUNCTION des32        RETURN PLS_INTEGER     AS     BEGIN       RETURN g_des32;  END; ---------------------------------------------------------     FUNCTION aes      RETURN PLS_INTEGER     AS     BEGIN     RETURN g_aes;  END; ---------------------------------------------------------    FUNCTION aes192        RETURN PLS_INTEGER     AS     BEGIN       RETURN g_aes192;   END; ---------------------------------------------------------    FUNCTION aes256       RETURN PLS_INTEGER     AS     BEGIN      RETURN g_aes256;  END; ---------------------------------------------------------     FUNCTION rc4       RETURN PLS_INTEGER     AS     BEGIN   RETURN g_rc4;   END; ---------------------------------------------------------    FUNCTION get_algorithm      RETURN VARCHAR2     -- returns string value for current encryption algorithm    AS         l_enc_algorithm  VARCHAR2 (6); BEGIN       CASE          WHEN g_enc_algorithm = g_des          THEN              l_enc_algorithm := 'DES';     WHEN g_enc_algorithm = g_des32          THEN              l_enc_algorithm := 'DES32';     WHEN g_enc_algorithm = g_des3         THEN       l_enc_algorithm := 'DES3';     WHEN g_enc_algorithm = g_aes          THEN           l_enc_algorithm := 'AES';     WHEN g_enc_algorithm = g_aes192         THEN           l_enc_algorithm := 'AES192';     WHEN g_enc_algorithm = g_aes256          THEN             l_enc_algorithm := 'AES256';     WHEN g_enc_algorithm = g_rc4        THEN            l_enc_algorithm := 'RC4';     END CASE;     RETURN l_enc_algorithm;   END; ---------------------------------------------------------     PROCEDURE set_algorithm (p_enc_algorithm IN PLS_INTEGER)   -- sets global encryption algorithm to p_enc_algorithm     -- check to ensure algorithm is valid     AS      l_err_msg  VARCHAR2 (200);   BEGIN        IF (p_enc_algorithm IN                 (g_des,            g_des3,            g_des32,            g_aes,            g_aes192,            g_aes256,            g_rc4))     THEN        g_enc_algorithm := p_enc_algorithm;     ELSE        l_err_msg :=            'Unsupported encryption algorithm: '         || 'Use one of the following DATA_CRYPTO variables: '         || 'DES, DES3, DES32, AES, AES192, AES256, RC4';       raise_application_error (-20001, l_err_msg);     END IF;   END; ---------------------------------------------------------     PROCEDURE setkey (     p_key            IN  VARCHAR2,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)   -- sets global encryption key to p_key. Key is sized      -- according to p_enc_algorithm or global algorithm      AS      BEGIN          -- check pad key and store        g_key := getkey (p_key, p_enc_algorithm);   END; ---------------------------------------------------------    FUNCTION get_key_size (p_enc_algorithm IN PLS_INTEGER)     RETURN PLS_INTEGER     -- return key size in bytes based on algorithm used    AS       l_blocks  PLS_INTEGER := 2; BEGIN       -- need case statement       CASE           WHEN NVL (p_enc_algorithm, g_enc_algorithm) = g_des         THEN           l_blocks := 1;     WHEN NVL (p_enc_algorithm, g_enc_algorithm) = g_des32           THEN            l_blocks := 3;     WHEN NVL (p_enc_algorithm, g_enc_algorithm) = g_des3         THEN           l_blocks := 3;     WHEN NVL (p_enc_algorithm, g_enc_algorithm) = g_aes         THEN            l_blocks := 2;     WHEN NVL (p_enc_algorithm, g_enc_algorithm) = g_aes192         THEN            l_blocks := 3;     WHEN NVL (p_enc_algorithm, g_enc_algorithm) = g_aes256         THEN           l_blocks := 4;     -- RC4 does not require key padding         END CASE;     RETURN l_blocks * 8;   END; ---------------------------------------------------------     FUNCTION padkey (p_key IN VARCHAR2)     RETURN VARCHAR2    -- Pads p_key out 8-bytes. Used to increase Key size     -- Padding to the right to preserve any uniqueness     -- presented with the key     AS     BEGIN          RETURN RPAD (p_key,                  (TRUNC (LENGTHB (p_key) / 8) + 1) * 8,                  CHR (0));  END; ---------------------------------------------------------     FUNCTION getkey (     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW      -- return raw key of size congruent with algorithm     -- only work on key if p_key is not null     AS        -- Key size changes based on algorithm       -- Need to compute key size based on the algorithm being used       -- Key size only restricted to block ciphers      l_key_size       PLS_INTEGER;   l_key            VARCHAR2 (32767) := NVL (p_key, g_key);   -- algorithm is passed. Actual determination done in getKeySize.   l_enc_algorithm  PLS_INTEGER;  BEGIN         -- if using RC4, no padding is required       IF (NVL (p_enc_algorithm, g_enc_algorithm) = rc4)   THEN           RETURN NVL (UTL_RAW.cast_to_raw (p_key), g_key);   END IF;   -- need to contract or expand key based on algorithm       l_key_size := get_key_size (p_enc_algorithm);   -- key may be too long. Truncate using first bytes        l_key := SUBSTR (l_key, 1, l_key_size);   -- if key is too short, we have to pad       WHILE LENGTH (l_key) < l_key_size       LOOP         l_key := padkey (l_key);   END LOOP;   -- last loop iteration may have made key too large       -- need to ensure key size is not too large.   -- also convert result to RAW        RETURN UTL_RAW.cast_to_raw (SUBSTR (l_key, 1,                                       l_key_size));   END; ---------------------------------------------------------     FUNCTION encrypt_char (     p_data           IN  VARCHAR2,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW   -- takes data and key in varchar2 and returns varchar2 encrytped data      -- Key and algorithm are passed, or default global value is used.   AS        -- convert data to RAW for crytpo algorithm        l_input      RAW (32767)                   := UTL_RAW.cast_to_raw (p_data);     l_algorithm  PLS_INTEGER                    := NVL (p_enc_algorithm, g_enc_algorithm);   BEGIN         RETURN dbms_crypto.encrypt                                (src    => l_input,                        typ    => l_algorithm,                        KEY    => getkey                                        (p_key,                                        l_algorithm));   END; ---------------------------------------------------------     FUNCTION decrypt_char (     p_data           IN  RAW,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2     -- takes encrypted varchar2 data and plaintext varchar2 key    -- and returns decrypted varchar2 data.  -- Key and algorithm are passed, or default global value is used.  AS        -- convert data to RAW for crytpo algorithm        l_algorithm  PLS_INTEGER             := NVL (p_enc_algorithm, g_enc_algorithm); BEGIN      RETURN UTL_RAW.cast_to_varchar2                      (dbms_crypto.decrypt                                     (src    => p_data,                         typ    => l_algorithm,                         KEY    => getkey                                                     (p_key,                                        l_algorithm))); END; ---------------------------------------------------------     FUNCTION encrypt (     p_data           IN  VARCHAR2,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2     -- Takes plaintext data and returns encrypted data as varchar2     -- Key and algorithm are passed, or default global value is used.  AS     BEGIN     RETURN UTL_RAW.cast_to_varchar2                            (encrypt_char (p_data,                                   p_key,                                   p_enc_algorithm));   END; ---------------------------------------------------------     FUNCTION decrypt (     p_data           IN  VARCHAR2,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2     -- takes encrypted varchar2 data     -- and returns decrypted varchar2 data.  -- Key and algorithm are passed, or default global value is used.  AS      -- convert data to RAW for crytpo algorithm     BEGIN       RETURN (decrypt_char                                     (UTL_RAW.cast_to_raw (p_data),                       p_key,                       p_enc_algorithm));   END; ---------------------------------------------------------     FUNCTION encrypt_number (     p_data           IN  NUMBER,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW     -- takes data and key in number format and returns raw encrytped data     -- Key and algorithm are passed, or default global value is used.  AS       -- convert data to RAW for crytpo algorithm        l_input      RAW (32767)                 := UTL_RAW.cast_from_number (p_data);    l_algorithm  PLS_INTEGER                        := NVL (p_enc_algorithm, g_enc_algorithm); BEGIN       RETURN dbms_crypto.encrypt                                  (src    => l_input,                      typ    => l_algorithm,                      KEY    => getkey                                                            (p_key,                                        l_algorithm));   END; ---------------------------------------------------------     FUNCTION decrypt_number (     p_data           IN  RAW,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN NUMBER     -- takes encrypted raw data and plaintext varchar2 key     -- and returns decrypted number data.  -- Key and algorithm are passed, or default global value is used.  AS         -- convert data to RAW for crytpo algorithm       l_algorithm  PLS_INTEGER              := NVL (p_enc_algorithm, g_enc_algorithm);  BEGIN          RETURN UTL_RAW.cast_to_number                  (dbms_crypto.decrypt                              (src    => p_data,                         typ    => l_algorithm,                         KEY    => getkey                                                       (p_key,                                        l_algorithm)));   END; ---------------------------------------------------------     FUNCTION encrypt_date (     p_data           IN  DATE,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW    -- takes date and key and returns raw encrytped data    -- Key and algorithm are passed, or default global value is used.  AS        -- convert data to RAW for crytpo algorithm       l_input      RAW (32767)         := UTL_RAW.cast_to_raw (TO_CHAR (p_data));     l_algorithm  PLS_INTEGER               := NVL (p_enc_algorithm, g_enc_algorithm); BEGIN       RETURN dbms_crypto.encrypt                                       (src    => l_input,                        typ    => l_algorithm,                        KEY    => getkey                                                        (p_key,                                        l_algorithm)); END; ---------------------------------------------------------     FUNCTION decrypt_date (     p_data           IN  RAW,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN DATE     -- takes encrypted raw data and plaintext varchar2 key   -- and returns decrypted date.   -- Key and algorithm are passed, or default global value is used.   AS        -- convert data to RAW for crytpo algorithm        l_algorithm  PLS_INTEGER             := NVL (p_enc_algorithm, g_enc_algorithm);   BEGIN        RETURN TO_DATE                    (UTL_RAW.cast_to_varchar2                    (dbms_crypto.decrypt                                   (src    => p_data,                         typ    => l_algorithm,                         KEY    => getkey                                                             (p_key,                                        l_algorithm))));   END; ---------------------------------------------------------     FUNCTION encrypt (     p_data           IN  CLOB,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN CLOB     -- encrypts a CLOB and return value as CLOB     -- done as function for performing SQL updates    AS        l_encrypted_blob  BLOB;     l_encrypted_clob  CLOB;     l_lang            NUMBER := DBMS_LOB.default_lang_ctx;     l_warning         NUMBER;     l_t_offset        NUMBER := 1;     l_src_offset      NUMBER := 1;  BEGIN          DBMS_LOB.createtemporary (l_encrypted_blob, TRUE);     DBMS_LOB.createtemporary (l_encrypted_clob, TRUE);     dbms_crypto.encrypt (dst    => l_encrypted_blob,                          src    => p_data,                          typ    => NVL (p_enc_algorithm,                                         g_enc_algorithm),                          KEY    => getkey (p_key,                                            p_enc_algorithm));     DBMS_LOB.converttoclob (l_encrypted_clob,                             l_encrypted_blob,                             DBMS_LOB.lobmaxsize,                             l_t_offset,                             l_src_offset,                             DBMS_LOB.default_csid,                             l_lang,                             l_warning);     RETURN l_encrypted_clob;   END; ---------------------------------------------------------     FUNCTION decrypt (     p_data           IN  CLOB,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN CLOB    -- decrypts a CLOB and return value as CLOB     -- done as function for performing SQL updates     AS         l_encrypted_blob  BLOB;     l_decrypted_blob  BLOB;     l_decrypted_clob  CLOB;     l_lang            NUMBER := DBMS_LOB.default_lang_ctx;     l_warning         NUMBER;     l_t_offset        NUMBER := 1;     l_src_offset      NUMBER := 1;  BEGIN         DBMS_LOB.createtemporary (l_encrypted_blob, TRUE);     DBMS_LOB.createtemporary (l_decrypted_blob, TRUE);     DBMS_LOB.createtemporary (l_decrypted_clob, TRUE);     DBMS_LOB.converttoblob (l_encrypted_blob,                             p_data,                             DBMS_LOB.lobmaxsize,                             l_t_offset,                             l_src_offset,                             DBMS_LOB.default_csid,                             l_lang,                             l_warning);     dbms_crypto.decrypt (dst    => l_decrypted_blob,                          src    => l_encrypted_blob,                          typ    => NVL (p_enc_algorithm,                                         g_enc_algorithm),                          KEY    => getkey (p_key,                                            p_enc_algorithm));     l_t_offset := 1;     l_src_offset := 1;     DBMS_LOB.converttoclob (l_decrypted_clob,                             l_decrypted_blob,                             DBMS_LOB.lobmaxsize,                             l_t_offset,                             l_src_offset,                             DBMS_LOB.default_csid,                             l_lang,                             l_warning);     RETURN l_decrypted_clob;   END; ---------------------------------------------------------    FUNCTION encrypt (     p_data           IN  BLOB,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN BLOB    -- encrypts a BLOB and return value as BLOB     -- done as function for performing SQL updates    AS        l_encrypted_blob  BLOB;  BEGIN         DBMS_LOB.createtemporary (l_encrypted_blob, TRUE);     dbms_crypto.encrypt (dst    => l_encrypted_blob,                          src    => p_data,                          typ    => NVL (p_enc_algorithm,                                         g_enc_algorithm),                          KEY    => getkey (p_key,                                            p_enc_algorithm));     RETURN l_encrypted_blob;   END; ---------------------------------------------------------    FUNCTION decrypt (     p_data           IN  BLOB,     p_key            IN  VARCHAR2 DEFAULT NULL,     p_enc_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN BLOB     -- decrypts a BLOB and return value as BLOB     -- done as function for performing SQL updates     AS        l_decrypted_blob  BLOB;  BEGIN         DBMS_LOB.createtemporary (l_decrypted_blob, TRUE);     dbms_crypto.decrypt (dst    => l_decrypted_blob,                          src    => p_data,                          typ    => NVL (p_enc_algorithm,                                         g_enc_algorithm),                          KEY    => getkey (p_key,                                            p_enc_algorithm));     RETURN l_decrypted_blob;   END; ---------------------------------------------------------   --                     HASHING                         --   ---------------------------------------------------------       -- Following functions return integer value of associated     -- hashing algorithm   ---------------------------------------------------------   FUNCTION md4       RETURN PLS_INTEGER      AS     BEGIN        RETURN g_md4;   END; ---------------------------------------------------------     FUNCTION md5       RETURN PLS_INTEGER     AS     BEGIN    RETURN g_md5;  END; ---------------------------------------------------------    FUNCTION sha       RETURN PLS_INTEGER    AS     BEGIN    RETURN g_sha;  END; ---------------------------------------------------------    FUNCTION get_hash_algorithm      RETURN VARCHAR2     -- return string representation of current hash algorithm    AS       l_hash_algorithm  VARCHAR2 (3);  BEGIN        CASE           WHEN g_hash_algorithm = g_md4            THEN            l_hash_algorithm := 'MD4';      WHEN g_hash_algorithm = g_md5          THEN            l_hash_algorithm := 'MD5';      WHEN g_hash_algorithm = g_sha           THEN             l_hash_algorithm := 'SHA';    END CASE;  RETURN l_hash_algorithm; END; ---------------------------------------------------------     PROCEDURE set_hash_algorithm (     p_hash_algorithm  IN  PLS_INTEGER)  -- sets global hashing algorithm to p_hash_algorithm    AS        l_err_msg  VARCHAR2 (50);  BEGIN       -- check to ensure algorithm is valid       IF (p_hash_algorithm IN (g_md4, g_md5, g_sha))  THEN         g_hash_algorithm := p_hash_algorithm;  ELSE         l_err_msg :=            'Unsupported Hash algorithm: '         || 'Use one of the following DATA_CRYPTO variables: '         || 'MD4, MD5, SHA';       raise_application_error (-20002, l_err_msg);     END IF;   END; ---------------------------------------------------------     FUNCTION hash2raw (     p_data            IN  VARCHAR2,     p_hash_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW    -- Computes hash and return value as RAW    -- Uses p_hash_algorithm if passed, else     -- uses the global variable     AS       l_input  RAW (32767) := UTL_RAW.cast_to_raw (p_data);  BEGIN       RETURN dbms_crypto.HASH (src    => l_input,                             typ    => NVL                                            (p_hash_algorithm,                                            g_hash_algorithm));   END; ---------------------------------------------------------     FUNCTION HASH (     p_data            IN  VARCHAR2,     p_hash_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2     -- Computes hash and return value as VARCHAR2     -- Delegates call to hash2raw function     AS  BEGIN           RETURN UTL_RAW.cast_to_varchar2                                                         (hash2raw (p_data,                                            p_hash_algorithm));   END; ---------------------------------------------------------   --            Hashed Message Authentication Codes      --   ---------------------------------------------------------       -- Following functions return integer value of associated   -- hmac algorithms   ---------------------------------------------------------     FUNCTION hmac_sha       RETURN PLS_INTEGER     AS      BEGIN       RETURN g_hmac_sha; END; ---------------------------------------------------------     FUNCTION hmac_md5       RETURN PLS_INTEGER     AS     BEGIN       RETURN g_hmac_md5;  END; ---------------------------------------------------------     FUNCTION get_hmac_algorithm        RETURN VARCHAR2     -- return string representation of current HMAC algorithm     AS        l_hash_algorithm  VARCHAR2 (3); BEGIN       CASE            WHEN g_hash_algorithm = g_hmac_md5          THEN            l_hash_algorithm := 'HMAC_MD5';      WHEN g_hash_algorithm = g_hmac_sha          THEN           l_hash_algorithm := 'HMAC_SHA';   END CASE;   RETURN l_hash_algorithm; END; ---------------------------------------------------------     PROCEDURE set_hmac_algorithm (     p_hash_algorithm  IN  PLS_INTEGER)  -- sets global hashing algorithm to p_hash_algorithm     AS       l_err_msg  VARCHAR2 (50);  BEGIN        -- check to ensure algorithm is valid       IF (p_hash_algorithm IN (g_hmac_md5, g_hmac_sha))    THEN          g_hmac_algorithm := p_hash_algorithm;    ELSE           l_err_msg :=            'Unsupported HMAC algorithm: '         || 'Use one of the following DATA_CRYPTO variables: '         || 'HMAC_MD5, HMAC_SHA';       raise_application_error (-20002, l_err_msg);    END IF;  END; ---------------------------------------------------------     FUNCTION mac2raw (     p_data            IN  VARCHAR2,     p_key             IN  VARCHAR2 DEFAULT NULL,     p_hash_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN RAW     -- Computes hash message authentication code.  -- Returns value as RAW     -- Uses p_hash_algorithm if passed, else    -- uses the global hmac variable     AS        l_input      RAW (32767)                             := UTL_RAW.cast_to_raw (p_data);     l_algorithm  PLS_INTEGER                                         := NVL (p_hash_algorithm, g_hmac_algorithm); BEGIN       IF (l_algorithm NOT IN (g_hmac_sha, g_hmac_md5))    THEN           raise_application_error                                  (-20003,                               'Unsupported HMAC algorithm.');    END IF;    RETURN dbms_crypto.mac (src    => l_input,                            typ    => l_algorithm,                            KEY    => getkey (p_key));  END; ---------------------------------------------------------     FUNCTION mac (     p_data            IN  VARCHAR2,     p_key             IN  VARCHAR2 DEFAULT NULL,     p_hash_algorithm  IN  PLS_INTEGER DEFAULT NULL)     RETURN VARCHAR2     -- Computes MAC and returns value as VARCHAR2     -- Delegates call to mac2raw function     AS    BEGIN          RETURN UTL_RAW.cast_to_varchar2                                                      (mac2raw (p_data,                                            p_key,                                            p_hash_algorithm));  END; ---------------------------------------------------------  END; /



Effective Oracle Database 10g Security by Design
Effective Oracle Database 10g Security by Design
ISBN: 0072231300
EAN: 2147483647
Year: 2003
Pages: 111

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net