首页 > 数据库 > Oracle > 【加密技术】Oracle11g 加密技术
--AES 256数据加密解密
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 in the encrypted_raw variable 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;- 1. Create a table for BLOB column:
create table table_lob (id number, loc blob);
-- 2. Insert 3 empty lobs for src/enc/dec:
insert into table_lob values (1, EMPTY_BLOB());
insert into table_lob values (2, EMPTY_BLOB());
insert into table_lob values (3, EMPTY_BLOB());
set echo on
set serveroutput on
declare
srcdata RAW(1000);
srcblob BLOB;
encrypblob BLOB;
encrypraw RAW(1000);
encrawlen BINARY_INTEGER;
decrypblob BLOB;
decrypraw RAW(1000);
decrawlen BINARY_INTEGER;
leng INTEGER;
begin
-- RAW input data 16 bytes
srcdata := hextoraw('6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D');
dbms_output.put_line('---');
dbms_output.put_line('input is ' || srcdata);
dbms_output.put_line('---');
-- select empty lob locators for src/enc/dec
select loc into srcblob from table_lob where id = 1;
select loc into encrypblob from table_lob where id = 2;
select loc into decrypblob from table_lob where id = 3;
dbms_output.put_line('Created Empty LOBS');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(srcblob);
IF leng IS NULL THEN
dbms_output.put_line('Source BLOB Len NULL ');
ELSE
dbms_output.put_line('Source BLOB Len ' || leng);
END IF;
leng := DBMS_LOB.GETLENGTH(encrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Encrypt BLOB Len NULL ');
ELSE
dbms_output.put_line('Encrypt BLOB Len ' || leng);
END IF;
leng := DBMS_LOB.GETLENGTH(decrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Decrypt BLOB Len NULL ');
ELSE
dbms_output.put_line('Decrypt BLOB Len ' || leng);
END IF;
-- 3. Write source raw data into blob:
DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.WRITEAPPEND (srcblob, 16, srcdata);
DBMS_LOB.CLOSE (srcblob);
dbms_output.put_line('Source raw data written to source blob');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(srcblob);
IF leng IS NULL THEN
dbms_output.put_line('source BLOB Len NULL ');
ELSE
dbms_output.put_line('Source BLOB Len ' || leng);
END IF;
/*
* Procedure Encrypt
* Arguments: srcblob -> Source BLOB
* encrypblob -> Output BLOB for encrypted data
* DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES
* Chaining : CBC
* Padding : PKCS5
* 256 bit key for AES passed as RAW
* ->
hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
* IV (Initialization Vector) for AES algo passed as RAW
* -> hextoraw('00000000000000000000000000000000')
*/
DBMS_CRYPTO.Encrypt(encrypblob,
srcblob,
DBMS_CRYPTO.AES_CBC_PKCS5,
hextoraw ('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'),
hextoraw('00000000000000000000000000000000'));
dbms_output.put_line('Encryption Done');
dbms_output.put_line('---');
leng := DBMS_LOB.GETLENGTH(encrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Encrypt BLOB Len NULL');
ELSE
dbms_output.put_line('Encrypt BLOB Len ' || leng);
END IF;
-- 4. Read encrypblob to a raw:
encrawlen := 999;
DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.READ (encrypblob, encrawlen, 1, encrypraw);
DBMS_LOB.CLOSE (encrypblob);
dbms_output.put_line('Read encrypt blob to a raw');
dbms_output.put_line('---');
dbms_output.put_line('Encrypted data is (256 bit key) ' || encrypraw);
dbms_output.put_line('---');
/*
* Procedure Decrypt
* Arguments: encrypblob -> Encrypted BLOB to decrypt
* decrypblob -> Output BLOB for decrypted data in RAW
* DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES
* Chaining : CBC
* Padding : PKCS5
* 256 bit key for AES passed as RAW (same as used during Encrypt)
* ->
hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
* IV (Initialization Vector) for AES algo passed as RAW (same as
used during Encrypt)
* -> hextoraw('00000000000000000000000000000000')
*/
DBMS_CRYPTO.Decrypt(decrypblob,
encrypblob,
DBMS_CRYPTO.AES_CBC_PKCS5,
hextoraw
('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'),
hextoraw('00000000000000000000000000000000'));
leng := DBMS_LOB.GETLENGTH(decrypblob);
IF leng IS NULL THEN
dbms_output.put_line('Decrypt BLOB Len NULL');
ELSE
dbms_output.put_line('Decrypt BLOB Len ' || leng);
END IF;
-- Read decrypblob to a raw
decrawlen := 999;
DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.READ (decrypblob, decrawlen, 1, decrypraw);
DBMS_LOB.CLOSE (decrypblob);
dbms_output.put_line('Decrypted data is (256 bit key) ' || decrypraw);
dbms_output.put_line('---');
DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (srcblob, 0);
DBMS_LOB.CLOSE (srcblob);
DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (encrypblob, 0);
DBMS_LOB.CLOSE (encrypblob);
DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite);
DBMS_LOB.TRIM (decrypblob, 0);
DBMS_LOB.CLOSE (decrypblob);
end;
/
truncate table table_lob;
drop table table_lob;


--1 使用钱包(wallet)作为外部安全模块,保存主密钥 --oracle建议对TDE使用一个单独的的钱包 --在sqlnet.ora中使用参数 ENCRYPTION_WALLET_LOCATION指定钱包的位置 ENCRYPTION_WALLET_LOCATION= (SOURCE=(METHOD=FILE)(METHOD_DATA= (DIRECTORY=/u02/app/oracle/product/11.2.0/dbhome_1/wallet))) --生成主密钥 SQL> ALTER SYSTEM SET ENCRYPTION KEY IDENTIFIED BY "oracle123"; --打开关闭钱包 SQL> ALTER SYSTEM SET ENCRYPTION WALLET OPEN IDENTIFIED BY "oracle123"; SQL> ALTER SYSTEM SET ENCRYPTION WALLET CLOSE IDENTIFIED BY "oracle123"; V$ENCRYPTION_WALLET displays information on the status of the wallet and the wallet location for TDE --重置主密钥 ALTER SYSTEM SET ENCRYPTION KEY IDENTIFIED BY "oracle321"; --数据库只有读取钱包中的主密钥才能加密解密数据 默认情况下,TDE 使用具有192位密钥长度 (AES192) 的 AES 加密算法。可以指定非默认加密算法 默认情况下,TDE使用salt选项,加密之前将随机码添加到明文,这样很难破解加密。可以使用no salt取消随机码添加 默认情况下,TDE使用SHA-1完整性算法生成Authentication Code (MAC),做完整性检查。可以使用nomac取消完整性检查, 这样会提高性能节省存储空间。 --注意:可以将钱包配置为autologin方式 --2 列加密 --启用列加密 CREATE TABLE em ( first_name VARCHAR2(128), last_name VARCHAR2(128), empid NUMBER, salary NUMBER(6) ENCRYPT ); --使用非默认加密算法 CREATE TABLE emp ( first_name VARCHAR2(128), last_name VARCHAR2(128), empid NUMBER, salary NUMBER(6) ENCRYPT USING '3DES168' NO SALT ); SQL> ALTER TABLE emp MODIFY (first_name ENCRYPT); --注意:在加密列上创建索引,加密列不能使用salt方式 SQL> ALTER TABLE employee MODIFY (first_name ENCRYPT NO SALT); create index first_name_indx on emp (first_name); --取消列加密 SQL> ALTER TABLE employee MODIFY (first_name DECRYPT); --3 表空间加密 --启用表空间加密 CREATE TABLESPACE securespace2 DATAFILE '/u02/app/oracle/secure01.dbf' SIZE 10M ENCRYPTION DEFAULT STORAGE(ENCRYPT); --DBA_TABLESPACES: The ENCRYPTED column indicates whether a tablespace is encrypted-- --USER_TABLESPACES: The ENCRYPTED column indicates whether a tablespace is encrypted --注意:You cannot access any encrypted data without the master encryption key --》管理TDE 1 启用AUTO LOGIN wallet --2 备份和管理主密钥 --如果没有主密钥是不能访问加密数据的,主密钥存储在wallet中,需要对wallet做备份 --当产生新的主密钥时必须备份wallet --备份时不应同时备份加密数据和钱包wallet,应单独备份wallet,以防止恶意用户同时获取加密数据和wallet钱包 --rman不会备份wallet --rman如果使用了Oracle Secure Backup OSB(如带库)会自动排除auto login wallet(cwallet.sso), 但不会排除普通的wallet(ewallet.p12 ),所以使用此备份方式,建议添加以下语句排除wallet exclude name *.p12 --如果存储主密钥的wallet丢失或损坏,将备份版本拷贝至适当位置即可恢复 --1 如果备份版本是上次重置主密钥之后版本,无需任何操作 --2 如果备份版本是上次重置主密钥之前版本,即不包含最新主密钥,则需要将数据库恢复至重置主密钥之前时间点。 之后的数据将丢失。================================ --》其他加密
--加密数据无法使用exp/imp工具移动,只能使用datapump移动数据, --导出TDE加密 数据时,必须打开钱包wallet,因为数据需要主密钥解密 --使用数据泵datapump或恢复管理器rman移动数据时,如果使用TDE加密功能,需要wallet。 也可以使用工具自带的加密功能单独加密数据。 --数据泵(datapump)加密 --1 涉及TDE数据时,需要wallet钱包打开,只适合本机原地操作。 --导出数据后,数据以非加密的形式存储在转储文件集中 expdp hr/hr TABLES=emp DIRECTORY=DATA_PUMP_DIR DUMPFILE=emp.dmp logfile=emp.expdp ORA-39173: Encrypted data has been stored unencrypted in dump file set. ALTER SYSTEM SET ENCRYPTION WALLET CLOSE IDENTIFIED BY "oracle123"; impdp \'/ as sysdba\' DIRECTORY=DATA_PUMP_DIR DUMPFILE=emp.dmp logfile=emp.impdp remap_schema=hr:test --如果想转储文件集也加密,可以单独指定以下参数(TDE数据解密后再加密) ENCRYPTION_PASSWORD ENCRYPTION = [ALL | DATA_ONLY | ENCRYPTED_COLUMNS_ONLY | METADATA_ONLY | NONE] ALL enables encryption for all data and metadata in the export operation. DATA_ONLY specifies that only data is written to the dump file set in encrypted format. ENCRYPTED_COLUMNS_ONLY specifies that only encrypted columns are written to the dump file set in encrypted format. To use this option, you must have Oracle Advanced Security transparent data encryption enabled. See Oracle Database Advanced Security Administrator's Guide for more information about transparent data encryption. METADATA_ONLY specifies that only metadata is written to the dump file set in encrypted format. NONE specifies that no data is written to the dump file set in encrypted format. ENCRYPTION不指定默认为all --2 不涉及TDE数据时,不需要wallet钱包,可单独加密转储文件集。适用于所有场景 expdp hr/hr TABLES=employees DIRECTORY=DATA_PUMP_DIR DUMPFILE=employees.dmp logfile=employees.expdp encryption_password=oracle impdp \'/ as sysdba\' DIRECTORY=DATA_PUMP_DIR DUMPFILE=employees.dmp logfile=employees.impdp remap_schema=hr:test ORA-39174: Encryption password must be supplied. encryption_password=oracle --RMAN备份加密 --1 使用TDE,适合本机原地操作 --1)创建钱包(已创建) --2)打开钱包 SQL> alter system set encryption wallet open identified by oracle; --3)开启RMAN加密功能 RMAN> configure encryption for database on; --4)备份与恢复命令不会发生更改,需要打开钱包 --5)通过命令可以暂时覆盖永久配置 RMAN> set encryption off; --2 口令模式设置(不需要钱包),使用与所有场景 RMAN> set encryption on identified by admin only; RMAN> backup datafile 4; RMAN> set decryption identified by admin; --还原时必须解密 RMAN> restore datafile 4; --3 如果创建了钱包,可以使用双重模式 SQL> alter system set encryption wallet open identified by oracle; RMAN> set encryption on identified by oracle; RMAN> backup datafile 4; SQL> alter system set encryption wallet close; --关闭钱包 RMAN> set decryption identified by oracle; --钱包、口令任选一个 SQL> alter system set encryption wallet open identified by oracle; RMAN> restore datafile 4; RMAN> recover datafile 4; RMAN> alter database open; --改变rman加密算法 SQL> select algorithm_name from v$rman_encryption_algorithms; RMAN> configure encryption algorithm 'AES192'; RMAN> set encryption algorithm 'AES256'; --relate view --在dba_tablespaces会添加新列encrypted让你查看状态 v$encryption_wallet v$encrypted_tablespaces
-- 在sqlnet.ora 文件里添加: ENCRYPTION_WALLET_LOCATION 和WALLET_LOCATION参数。 默认位置是:$ORACLE_BASE/admin/$ORACLE_SID/wallet。 --指定ORACLE WALLET的位置,这里使用ORACLE_HOME/network/admin,在sqlnet.ora里添加如下内容: WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (DIRECTORY= /u01/app/oracle/product/11.2.0/db_1/network/admin) ) ) ENCRYPTION_WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (DIRECTORY= /u01/app/oracle/admin/dave/wallet) ) ) SQLNET.WALLET_OVERRIDE = TRUE SSL_CLIENT_AUTHENTICATION = FALSE SSL_VERSION = 0 --添加完之后,重启listener,使参数生效。 --创建wallet:包括设置密码、生成信任文件、并启动wallet CONN / AS SYSDBA -- 10g version ALTER SYSTEM SET ENCRYPTIONKEYAUTHENTICATED BY "myPassword"; -- 11g version ALTER SYSTEM SET ENCRYPTIONKEYIDENTIFIED BY "myPassword"; 当实例重启后或者wallet被关闭后,必须重新open wallets,这样才能保护被加密的列. 而在Openwallet之前,数据库必须处于mount 状态。 SQL>STARTUP MOUNT; SQL> ALTERSYSTEM SET ENCRYPTION WALLET OPEN IDENTIFIED BY "myPassword"; SQL>ALTER DATABASE OPEN; -- 10g version ALTER SYSTEM SET ENCRYPTION WALLET OPEN AUTHENTICATEDBY "myPassword"; -- 11g version ALTER SYSTEM SET ENCRYPTION WALLET OPEN IDENTIFIEDBY "myPassword"; --关闭Wallet: ALTER SYSTEM SET ENCRYPTIONWALLET CLOSE IDENTIFIED BY "myPassword"; --使用SQL 创建的wallet 的问题是不能自动登陆,这样我们在关闭wallet或者重启实例后, 都需要手动的来open wallet。 这样有点麻烦,Oracle 提供了wallet 自动登陆功能,可以在创建wallet指定该属性, 也可以在创建后使用owm(Oracle wallet manager)来修改。 --也可使用orapki,显示 orapki wallet display -wallet /u01/app/oracle/admin/dave/encryption_wallet --修改密码 orapki wallet change_pwd -wallet wallet_location[-oldpwd password ] [-newpwd password] --创建自动登录 orapki wallet create -wallet wallet_location -auto_login_only 相关试图: V$ENCRYPTION_WALLET v$wallet dba_encrypted_columns
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29487349/viewspace-2697013/ ,如需转载,请注明出处,否则将追究法律责任。