Encrypt or Decrypt sensitive data using PLSQL - DBMS_CRYPTO
Oracle 10g introduced Transparent Data Encryption, which is about storing data physically as encrypted in data files. The users always create/retrieve data as plain text. When the data is created, user provides plain text but Oracle automatically converts that plain text into encrypted form and stores it in the data files and whenever users access that data, Oracle decrypts the data and show it to the users. This encryption and decryption is completely transparent to the users. They never know that data was encrypted. The whole point behind transparent encryption is to keep the sensitive data in the data files safe.
Oracle 10g引进TDE(透明数据加密),由数据文件存储加密数据。用户无需关心加密过程,可正常创建/查询平面文本。
Encrypting sensitive data for users or applications is a different thing at all and has no similarity with Transparent Data Encryption. If you want some column in the table to be shown as encrypted to the users, then you will have to encrypt it yourself at the time of creating that data. And when you want to use that data you will have to decrypt it first. Oracle provides utilities to perform encryption and decryption, e.g. DBMS_OBFUSCATION_KIT in 8i and 9i. This package was replaced by DBMS_CRYPTO in 10g, is more easier to use and have more cryptographic algorithms.
8i和9i可以使用DBMS_OBFUSCATION_KIT 包,10g使用DBMS_CRYPTO 包。
本案例将实现加密SCOTT用户下users表的password列:
In this tutorial we will use a "users" table with a field "password". The password field is suppose to show an encrypted value when queried, but should give the real password value (decrypted) when needed by the application.
$ sqlplus scott/tiger CREATE TABLE users (
userid NUMBER,
username VARCHAR2(30),
userlocation VARCHAR2(30),
password VARCHAR2(200),
CONSTRAINT users_pk PRIMARY KEY (userid)
); insert into users
values (1,'JAMES','TEXAS','james123'); insert into users
values (2,'JONES','TEXAS','jones001'); insert into users
values (3,'ALLEN','TEXAS','allen789'); commit; exit;
We just created the table and created some plain text passwords. Lets now develop an encryption/decryption mechanism for the password field.
$ sqlplus / as sysdba CREATE OR REPLACE PACKAGE enc_dec
AS
FUNCTION encrypt (p_plainText VARCHAR2) RETURN RAW DETERMINISTIC;
FUNCTION decrypt (p_encryptedText RAW) RETURN VARCHAR2 DETERMINISTIC;
END;
/ CREATE OR REPLACE PACKAGE BODY enc_dec
AS
encryption_type PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_DES
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
/*
ENCRYPT_DES is the encryption algorithem. Data Encryption Standard. Block cipher.
Uses key length of 56 bits.
CHAIN_CBC Cipher Block Chaining. Plaintext is XORed with the previous ciphertext
block before it is encrypted.
PAD_PKCS5 Provides padding which complies with the PKCS #5: Password-Based
Cryptography Standard
*/
encryption_key RAW (32) := UTL_RAW.cast_to_raw('MyEncryptionKey');
-- The encryption key for DES algorithem, should be 8 bytes or more. FUNCTION encrypt (p_plainText VARCHAR2) RETURN RAW DETERMINISTIC
IS
encrypted_raw RAW (2000);
BEGIN
encrypted_raw := DBMS_CRYPTO.ENCRYPT
(
src => UTL_RAW.CAST_TO_RAW (p_plainText),
typ => encryption_type,
key => encryption_key
);
RETURN encrypted_raw;
END encrypt;
FUNCTION decrypt (p_encryptedText RAW) RETURN VARCHAR2 DETERMINISTIC
IS
decrypted_raw RAW (2000);
BEGIN
decrypted_raw := DBMS_CRYPTO.DECRYPT
(
src => p_encryptedText,
typ => encryption_type,
key => encryption_key
);
RETURN (UTL_RAW.CAST_TO_VARCHAR2 (decrypted_raw));
END decrypt;
END;
/ grant execute on enc_dec to scott;
create public synonym enc_dec for sys.enc_dec; exit;
Using the same encryption algorithm and key, the functions "encrypt" and "decrypt" will always produce same results for same input parameters e.g. for a value ABC the function will always return same encrypted value. Therefore, it makes a lot of sense to create these functions as deterministic. Once a function is created as deterministic, and is being executed second time against same input parameters, Oracle doesn't really executes it the second time but it uses the results of its previous execution against the same input which increases the performance to a high extent.
The encryption or decryption on VARCHAR2 doesn't work directly using DBMS_CRYPTO, therefore, I have converted it to RAW before encrypting it.
For more information of cryptographic algorithms please see:
DBMS_CRYPTO Algorithms
$ sqlplus scott/tiger
select enc_dec.encrypt('Hello World') encrypted
from dual;
ENCRYPTED
----------------------------------
89738046FA0CFDD2581198FBF98DE2C5
/* A simple value encrypted using the package we just created. */
select enc_dec.decrypt('89738046FA0CFDD2581198FBF98DE2C5') decrypted
from dual;
DECRYPTED
------------------
Hello World
/* The same value decrypted using the package we just created. */
column username format a10
column userlocation format a10
column password format a10
select * from users;
USERID USERNAME USERLOCATI PASSWORD
---------- ---------- ---------- ----------
1 JAMES TEXAS james123
2 JONES TEXAS jones001
3 ALLEN TEXAS allen789
/* We can see Password data in plain text from above. */
SQL> update users
2 set password = enc_dec.encrypt (password);
3 rows updated.
SQL> commit;
Commit complete.
/*
We just encrypted the password data using the algorithm and key specified in the
package ENC_DEC.
We also need to make sure any newly created record has Password value encrypted using
the package ENC_DEC.
*/
column password format a32
select * from users;
USERID USERNAME USERLOCATI PASSWORD
---------- ---------- ---------- --------------------------------
1 JAMES TEXAS D705C2186A64B1A6FF3B6E6220746731
2 JONES TEXAS 98DDCC4DAB5F13140C8D657D381E05FC
3 ALLEN TEXAS D9A656AD83B7ADC7443D6BECD173715E
/* All existing passwords are now encrypted */
SQL> insert into users
2 values (4,'SCOTT','TEXAS',enc_dec.encrypt('scott456'));
1 row created.
SQL> commit;
Commit complete.
SQL> select * from users;
USERID USERNAME USERLOCATI PASSWORD
---------- ---------- ---------- --------------------------------
1 JAMES TEXAS D705C2186A64B1A6FF3B6E6220746731
2 JONES TEXAS 98DDCC4DAB5F13140C8D657D381E05FC
3 ALLEN TEXAS D9A656AD83B7ADC7443D6BECD173715E
4 SCOTT TEXAS 41D69256E23E7A3D2AFEFF2E5C082FFD
/* The newly created record of user SCOTT has its password encrypted. */
column decrypted_password format a10
column encrypted_password format a32
select username ,
enc_dec.decrypt (password) decrypted_password,
password encrypted_password
from users;
USERNAME DECRYPTED_ ENCRYPTED_PASSWORD
---------- ---------- --------------------------------
JAMES james123 D705C2186A64B1A6FF3B6E6220746731
JONES jones001 98DDCC4DAB5F13140C8D657D381E05FC
ALLEN allen789 D9A656AD83B7ADC7443D6BECD173715E
SCOTT scott456 41D69256E23E7A3D2AFEFF2E5C082FFD
SQL> grant select on users to hr;
Grant succeeded.
These encrypted values can only be seen by the users who have EXECUTE access to the ENC_DEC package. The data can only be decrypted using the same key and algorithem it was encrypted with. So all these password values can only be decrypted using the KEY and ALGORITHEM specified in the package ENC_DEC.
I have granted SELECT on table "users" to HR. Lets see what he sees when he querys data from users tables.
SQL> conn hr/hr
Connected.
column username format a10
column userlocation format a10
column password format a32
select * from scott.users; USERID USERNAME USERLOCATI PASSWORD
---------- ---------- ---------- --------------------------------
1 JAMES TEXAS D705C2186A64B1A6FF3B6E6220746731
2 JONES TEXAS 98DDCC4DAB5F13140C8D657D381E05FC
3 ALLEN TEXAS D9A656AD83B7ADC7443D6BECD173715E
4 SCOTT TEXAS 41D69256E23E7A3D2AFEFF2E5C082FFD SQL> select enc_dec.decrypt(password) from scott.users;
select enc_dec.decrypt(password) from scott.users
*
ERROR at line 1:
ORA-00904: : invalid identifier SQL> desc enc_dec
ERROR:
ORA-04043: object "SYS"."ENC_DEC" does not exist
Since the user HR has no access on the ENC_DEC package he cannot see the encrypted data.
Keep your encrypted data safe from intruders
Its all about keeping your encryption algorithm and key hidden. If they are exposed, anyone can decrypt your encrypted data and see it all. In our case the key and the algorithm is stored in the ENC_DEC package itself.
encryption_key RAW (32) := UTL_RAW.cast_to_raw('MyEncryptionKey');
encryption_type PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_DES
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
Anyone having DBA privileges can see the source code of the package and leak out the encryption algorithm with the key. We must wrap the code to hide the stuff in the code before we create or ship the package with the application. Here is how to wrap your PL/SQL code to hide it from users.
I put CREATE PACKAGE statements in a file named create_enc_dec_package.sql and then run the wrap utility to wrap the code into a new file named create_enc_dec_package.wrp.
$ wrap iname=create_enc_dec_package.sql oname=create_enc_dec_package.wrp PL/SQL Wrapper: Release 10.2.0.1.0- Production on Sun Aug 15 06:44:32 2010 Copyright (c) 1993, 2004, Oracle. All rights reserved. Processing create_enc_dec_package.sql to create_enc_dec_package.wrp
Lets see the contents of this new file create_enc_dec_package.wrp.
$ more create_enc_dec_package.wrp
CREATE OR REPLACE PACKAGE enc_dec wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
9
a6 b2
ceYtyd1wwstfJ/3xbNlo4sobVxYwg0xHAMusaS/pOPYrUgzeeSYbTuJ789ScOKWw4LWYL191
ERLxTlyzbW7nRf8Cg4W0plfc4t7qD8d69uAPwYNtQpv3U6F9kwZQZnVeV+a5FlnUcEgL7J8k
hQZIhcYLQoTZ/irf0ixRnEj+4VqG1c4= /
CREATE OR REPLACE PACKAGE BODY enc_dec wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
The wrap utility actually has encrypted the PL/SQL code in the .sql file, and made it unreadable for anyone. Now use create_enc_dec_package.wrp file to create the package. Keep your .sql source file safe with you as if you want to make changes to the package later on, you will need it i.e. make changes to the .sql file, wrap it again and recreate the package.
$ sqlplus / as sysdba Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options SQL> @create_enc_dec_package.wrp Package created. Package body created. SQL> column text format a70
SQL> select text from dba_source where name = 'ENC_DEC'; TEXT
----------------------------------------------------------------------
PACKAGE enc_dec wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
9
a6 b2
ceYtyd1wwstfJ/3xbNlo4sobVxYwg0xHAMusaS/pOPYrUgzeeSYbTuJ789ScOKWw4LWYL1
91
ERLxTlyzbW7nRf8Cg4W0plfc4t7qD8d69uAPwYNtQpv3U6F9kwZQZnVeV+a5FlnUcEgL7J
8k
hQZIhcYLQoTZ/irf0ixRnEj+4VqG1c4= PACKAGE BODY enc_dec wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
b
40a 1de
e5uq2Fhk2UgpK5ktxFEVOrE3zyowg5DxLdxqfC9AWE6OGeznw1zpVqLpwIrvVN522Z83WR
wv
HQw142Mg0KQxSHaso6WOT7ud5P5VvVmrcR3le4Pvj9tpyogriMDGGQGWIR5T3g4s5tMka+
Qj
TA4FsoMpOy3+bK/y/VW+u8+zHHC1m0LOziMSmnhkB+nM+U1jEvvRFGGXfOJrOSmXs+VcyV
r8
pyIFRQgr3JDZotwcfIZAw10k4Dcm87LMeBk6c0q2wdqgqcA422/awXKrAODetRti870jST
pn
46w5MWX/ickZHdrfBh6mMttQ8x4jDaNEcZR3X7VRdReUt05S6/LToL4T/VwlYFIqbzH7rb
OR
kaEYBQchlWDg5n3hRBahHVLvEeOuoQVsdBqMwA55PfP1yqqsYWSBW4Mm4OYFJP/ry1NJYb
bA
wVAA/SBw965bdu5doXjpf6y7D5dHh5dtIOL9uUA= SQL>
As can be seen that after creating the package from wrapped sql script the package source code is unreadable to anyone, even the owner of the package. This way we can hide the encryption logic completely from every one.
Encrypt or Decrypt sensitive data using PLSQL - DBMS_CRYPTO的更多相关文章
- oracle加密encrypt,解密decrypt
目录 oracle加密encrypt,解密decrypt 加密 解密 oracle加密encrypt,解密decrypt 有的oracle版本没有加解密函数,以下操作可以手动添加 oracle数据使用 ...
- js读取cookie,并利用encrypt和decrypt加密和解密方法
以下为支持encrypt和decrypt加密和解密方法 eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a ...
- Use Dynamic Data Masking to obfuscate your sensitive data
Data privacy is a major concern today for any organization that manages sensitive data or personally ...
- encrypt and decrypt data
https://www.cyberciti.biz/tips/linux-how-to-encrypt-and-decrypt-files-with-a-password.html Encryptin ...
- C# 加密(Encrypt) 解密(Decrypt) 操作类 java与 C# 可以相互加密解密
public sealed class EncryptUtils { #region Base64加密解密 /// <summary> /// Base64加密 /// </summ ...
- /encrypt和/decrypt端点来进行加密和解密的功能
- 微信破解,解密?How To Decrypt WeChat EnMicroMsg.db Database?
20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送) 国内私募机构九鼎控股打造,九鼎投资是在全国股 ...
- 关于 Java 对象序列化您不知道的 5 件事
数年前,当和一个软件团队一起用 Java 语言编写一个应用程序时,我体会到比一般程序员多知道一点关于 Java 对象序列化的知识所带来的好处. 关于本系列 您觉得自己懂 Java 编程?事实上,大多数 ...
- Chapter 6 — Improving ASP.NET Performance
https://msdn.microsoft.com/en-us/library/ff647787.aspx Retired Content This content is outdated and ...
- 疯狂Java学习笔记(84)----------大约 Java 对象序列化,你不知道 5 事
几年前,.当一个软件团队一起用 Java 书面申请.我认识比一般程序猿多知道一点关于 Java 对象序列化的知识所带来的优点. 关于本系列 您认为自己懂 Java 编程?其实,大多数程序猿对于 Jav ...
随机推荐
- Go-稀疏数组
package main import "fmt" // 稀疏数组 // 1. 二维数组 // 2. 存在大量相同相同数据和少量不同数据 // 思维: 将大量相同数据转化为: (数 ...
- [转帖]MySQL运维实战(2)MySQL用户和权限管理
https://segmentfault.com/a/1190000044514403 作者:俊达 引言 MySQL数据库系统,拥有强大的控制系统功能,可以为不同用户分配特定的权限,这对于运维来说至关 ...
- Harbor的逻辑备份与学习
Harbor的逻辑备份与学习 背景 一直想处理一下一个有网络冲突的Harbor镜像服务器 但是因为网络层自己水平一直是不是非常自信 加上Harbor容器使用的compose的玩法, 自己不敢直接处理. ...
- [转帖]《Linux性能优化实战》笔记(24)—— 动态追踪 DTrace
使用 perf 对系统内核线程进行分析时,内核线程依然还在正常运行中,所以这种方法也被称为动态追踪技术.动态追踪技术通过探针机制来采集内核或者应用程序的运行信息,从而可以不用修改内核和应用程序的代码就 ...
- Linux上面批量更新SQLSERVER SQL文本文件的办法
1. 今天同事让帮忙更新几个SQL文件.. 本着自己虽然low 但是不能太low的想法, 简单写一个 shell 脚本来执行. 2. 因为我的linux 里面都安装了 sqlcmd 的工具 所以办法就 ...
- Oracle DBCA 静默删除以及建库的脚本
No.1 背景 公司最近有一个测试环境需要重新备份恢复 但是里面有6个数据库实例 400多G的数据文件. 一般情况下 需要drop user xxx cascade ; 然后执行 drop table ...
- 【代码分享】使用 avx2 + 查表法,优化凯撒加密
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 接上一篇:[代码分享]使用 avx512 + 查表法,优化 ...
- VictoriaMetrics 1.84.0发布
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 11.25日,valyala大神发布了VictoriaMe ...
- vm-insert到vm-storage链路上的配置说明
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 本文是为了解决Victoria-Metrics中的过载问题 ...
- Jupyter Notebook支持Go
在执行下列命令之前,请确保你已经安装了Go和Jupyter. gophernotes是针对Jupyter和nteract的Go内核,它可以让你在基于浏览器的笔记本或桌面app上交互式地使用Go.下面介 ...