Sie sind auf Seite 1von 14

CREATE OR REPLACE

PACKAGE BODY encrypt_paswd


AS
G_CHARACTER_SET VARCHAR2(10) := 'AL32UTF8';
G_STRING VARCHAR2(32) := '12345678901234567890123456789012';
G_KEY RAW(250) := utl_i18n.string_to_raw
( data => G_STRING,
dst_charset => G_CHARACTER_SET );
G_ENCRYPTION_TYPE PLS_INTEGER := dbms_crypto.encrypt_aes256
+ dbms_crypto.chain_cbc
+ dbms_crypto.pad_pkcs5;
------------------------------------------------------------------------
--Encrypt a password
--Salt the password
------------------------------------------------------------------------
FUNCTION encrypt_val( p_val IN VARCHAR2 ) RETURN RAW
IS
l_val RAW(32) := UTL_I18N.STRING_TO_RAW( p_val, G_CHARACTER_SET );
l_encrypted RAW(32);
BEGIN
l_val := utl_i18n.string_to_raw
( data => p_val,
dst_charset => G_CHARACTER_SET );

l_encrypted := dbms_crypto.encrypt
( src => l_val,
typ => G_ENCRYPTION_TYPE,
key => G_KEY );

RETURN l_encrypted;
END encrypt_val;
END encrypt_paswd;
This uses encrypt_aes256 -"Advanced Encryption Standard. Block cipher. Uses 256-bit key size."
, chain_cbc- "Cipher Block Chaining. Plaintext is XORed with the previous ciphertext block
before it is encrypted." and pad_pkcs5 - "Provides padding which complies with the PKCS #5:
Password-Based Cryptography Standard".

In addition to this You can create a similar function to decrypt. like -

FUNCTION decrypt_val( p_val IN RAW ) RETURN VARCHAR2


IS
l_decrypted RAW(32);
l_decrypted_string VARCHAR2(32);
l_user VARCHAR2(32);
BEGIN
SELECT user
INTO l_user
FROM dual;

if l_user = 'ADMIN' -- you can restrict usage of decrypt to certain db users only.
then
l_decrypted := dbms_crypto.decrypt
( src => p_val,
typ => G_ENCRYPTION_TYPE,
key => G_KEY );

l_decrypted_string := utl_i18n.raw_to_char
( data => l_decrypted,
src_charset => G_CHARACTER_SET );
RETURN l_decrypted_string;
else
RAISE_APPLICATION_ERROR(-20101, 'You are not authorized to use this function -
decrypt_val()');
end if;
RETURN 'Unknown';
END decrypt_val;
ENCRYPTED DATA IN VARCHAR2 COLUMN

A table is created to record the data that will be encrypted. Then some example rows are inserted
on it.

drop table tab_dbms_crypto purge

Table dropped

create table tab_dbms_crypto(

account_name varchar2(60 byte),

account_passwd varchar2(256 byte)

Table created

--Inserting some rows into table

insert into

tab_dbms_crypto

(account_name,

account_passwd)

values
('user1', '#123$')

1 row inserted

insert into

tab_dbms_crypto

(account_name,

account_passwd)

values

('user2', '$456%')

1 row inserted

insert into

tab_dbms_crypto

(account_name,

account_passwd)

values

('user3', '(876%')

/
1 row inserted

commit

Commit complete

The table below is created to store encrypted data.

drop table tab_dbms_crypto_secrets purge;

Table dropped

create table tab_dbms_crypto_secrets(

value1 varchar2(128 byte),

value2 raw(128)

Table created

Now a package that will execute the process of encrypting and decrypting data is created using
these functions:

encrypt_aes128: Advanced encryption standard. Block cipher. Uses 128-bit key.

chain_cbc: Cipher block chaining

pad_pkcs5: Password-based cryptography standard


randombytes: This function generates random key values

create or replace package pkg_encrypt_decrypt

as

function enc_account_passwd(

p_account_passwd in varchar2,

p_account_name in varchar2,

p_unlock_code in varchar2 default null)

return varchar2;

function dec_account_passwd(

p_account_passwd in varchar2,

p_account_name in varchar2,

p_unlock_code in varchar2 default null)

return varchar2;

end;

Package created

create or replace package body pkg_encrypt_decrypt as

main_password varchar2(32) := 'ThisIsTheSuperSe';

free_passsword varchar2(10) := 'OpenSesame';

enc_mode number := dbms_crypto.encrypt_aes128 +


dbms_crypto.chain_cbc +

dbms_crypto.pad_pkcs5;

function enc_account_passwd(

p_account_passwd in varchar 2,

p_account_name in varchar 2,

p_unlock_code in varchar 2 default NULL)

return varchar2 as

swordfish raw(256);

swordfish_enccrypted raw(256);

begin

if (p_unlock_code is null or p_unlock_code != free_password)

then

return null;

end if;

The randombytes function below returns a raw value containing an encrypted secure pseudo-
random sequence of bytes which can be used to generate random material for encryption keys.

--We generate the swordfish, this ?random? number will be needed to decrypt the password

swordfish := dbms_crypto.randombytes(16);

-- This function encrypts raw data using a stream or block cipher with a user supplied key
enccrypted swordfish:= dbms_crypto.encrypt(swordfish,

enc_mode,

utl_i18n.string_to_raw(

main_password,

'al32utf8')); --Notice how easy it is to perform the conversion to raw

swordfish_enccrypted := dbms_crypto.encrypt(swordfish,

enc_mode,

utl_i18n.string_to_raw(

main_password,

'al32utf8'));

-- Inserting the account name, and swordfish, encrypted using the main_password as key, in
secrets table

insert into

tab_dbms_crypto_secrets

values

(p_account_name, enccrypted swordfish);

At this point, the password storage on column account_passwd is returned as an encrypted


account_passwd random key.

return
utl_encode.base64_encode(

dbms_crypto.encrypt(

utl_i18n.string_to_raw(

p_account_passwd,

'al32utf8'),

enc_mode,

swordfish));

end;

function dec_account_passwd(

p_account_passwd in varchar2,

p_account_name in varchar2,

p_unlock_code in varchar2 default NULL)

return varchar2 as

swordfish raw(256);

begin

if (p_unlock_code is null or p_unlock_code != free_passsword)

then

return null;

end if;

select

dbms_crypto.decrypt(
value2,

enc_mode,

utl_i18n.string_to_raw(

main_password,

'al32utf8'))

into

swordfish

from

tab_dbms_crypto_secrets

where

value1 = p_account_name;

return utl_i18n.raw_to_char(

dbms_crypto.decrypt(

utl_encode.base64_decode(

p_account_passwd),

enc_mode,

swordfish),

'al32utf8');

end;

end;

Package body created


Now the data without encryption is selected.

select

from

tab_dbms_crypto

ACCOUNT_NAME ACCOUNT_PASSWD

------------ --------------

user1 #123$

user2 $456%

user3 (876%

Here, the data is encrypted using the package and function created in the first steps.

update

tab_dbms_crypto

set

account_passwd = pkg_encrypt_decrypt.enc_account_passwd(

account_passwd,

account_name,
'OpenSesame')

3 rows updated

commit

Commit complete

Finally, the encrypted data can be seen.

select

from

tab_dbms_crypto

ACCOUNT_NAME ACCOUNT_PASSWD

-------------- ------------------------------------------------

user1 6E42464477424C7145733576626F666F766D79344E773D3D

user2 715961684967525655486D6B31736E2F4E4C747639513D3D

user3 4B5742784C6F3857783346454E58346A58396A5338673D3D
Just as with encrypt, decrypt can be done using the package and function created.

update

tab_dbms_crypto

set

account_passwd = pkg_encrypt_decrypt.dec_account_passwd(

account_passwd,

account_name,

'OpenSesame')

3 rows updated

commit

Commit complete

--Get the data without encryption again

select

from
tab_dbms_crypto

ACCOUNT_NAME ACCOUNT_PASSWD

------------ -----------------

user1 #123$

user2 $456%

user3 (876%

This example uses the function randombytes. This function returns a raw value containing a
cryptographically secure pseudo-random sequence of bytes which can be used to generate
random material for encryption keys.

The decrypt and encryptfunctions are also employed to encrypt and decrypt the raw data. Note
that the following functions are called in order to find information related to cryptographic data
in the database:

all_encrypted_columns

dba_encrypted_columns

user_encrypted_columns

v$encrypted_tablespaces

v$encryption_wallet

v$rman_encryption_algorithms

Das könnte Ihnen auch gefallen