Oracle AES加解密Demo

  1. 近期要使用Apex与其他系统做对接其中有一些敏感字段,已经加密.所以要使用Oracle解密. 以下是对应PL/SQL的Demo代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
create or replace PACKAGE CRYPTO_AES_PKG IS
/*
-- 使用demo
declare
l_key varchar2(200) := 'aaaaaaaa';
l_data varchar2(200) := '123456';
l_en varchar2(400);
l_de varchar2(400);
begin
-- 加密
l_en := CRYPTO_AES_PKG.F_ENCRYPT(l_data, l_key);
DBMS_OUTPUT.PUT_LINE(l_en); -- FP7MsKoQifAW311/XPIzLQ==
-- 解密
l_de := CRYPTO_AES_PKG.F_DECRYPT(l_en, l_key);
DBMS_OUTPUT.PUT_LINE(l_de); -- 123456
end;

*/
-- 加密
FUNCTION F_ENCRYPT(I_INPUT_STRING VARCHAR2, I_KEY_STRING varchar2) RETURN VARCHAR2;
-- 解密
FUNCTION F_DECRYPT(I_INPUT_STRING VARCHAR2, I_KEY_STRING VARCHAR2) RETURN VARCHAR2;
END;
create or replace PACKAGE BODY CRYPTO_AES_PKG IS
--加密
FUNCTION F_ENCRYPT(I_INPUT_STRING VARCHAR2, I_KEY_STRING varchar2) RETURN VARCHAR2
IS
V_KEY_STRING RAW(128) := utl_raw.cast_to_raw(
sys.dbms_obfuscation_toolkit.md5(input_string => I_KEY_STRING)); -- 加密串,同时也是解密串
V_ENCRYPTED_RAW RAW(200);
encryption_type pls_integer := DBMS_Crypto.ENCRYPT_AES128 + DBMS_Crypto.CHAIN_ECB + DBMS_Crypto.PAD_PKCS5;
BEGIN
V_ENCRYPTED_RAW := DBMS_CRYPTO.ENCRYPT(
SRC => UTL_I18N.STRING_TO_RAW(I_INPUT_STRING, 'AL32UTF8'),-- 被加密的字符串
TYP => encryption_type, -- DBMS_CRYPTO.AES_CBC_PKCS5 -- 加密算法,算法有很多
KEY => V_KEY_STRING);
-- 加密串
-- RETURN (RAWTOHEX(V_ENCRYPTED_RAW));
RETURN (UTL_I18N.RAW_TO_CHAR(utl_encode.base64_encode(RAWTOHEX(V_ENCRYPTED_RAW))));
END F_ENCRYPT;
--解密
FUNCTION F_DECRYPT(I_INPUT_STRING VARCHAR2, I_KEY_STRING VARCHAR2) RETURN VARCHAR2
IS
V_KEY_STRING RAW(128) := utl_raw.cast_to_raw(
sys.dbms_obfuscation_toolkit.md5(input_string => I_KEY_STRING));-- 加密串,同时也是解密串
V_DECRYPTED_RAW RAW(200);
b64_de RAW(200);
encryption_type pls_integer := DBMS_Crypto.ENCRYPT_AES128 + DBMS_Crypto.CHAIN_ECB + DBMS_Crypto.PAD_PKCS5;
BEGIN
b64_de := utl_encode.base64_decode(utl_raw.cast_to_raw(I_INPUT_STRING));
V_DECRYPTED_RAW := DBMS_CRYPTO.DECRYPT(
SRC => HEXTORAW(b64_de),
TYP =>encryption_type,
KEY => V_KEY_STRING);

RETURN (
-- UTL_RAW.CAST_TO_VARCHAR2(V_DECRYPTED_RAW)
UTL_I18N.RAW_TO_CHAR(V_DECRYPTED_RAW, 'AL32UTF8')
);
END F_DECRYPT;
END CRYPTO_AES_PKG;
  1. 附带一个Python的Demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import base64
import hashlib
from Crypto.Cipher import AES


class AESDecryptDBPassWD:
def __init__(self, key, signature):
self.md5 = hashlib.md5(key.encode())
self.key = key
self.signature = signature
self.block_size = 16
self.pad = lambda passwd: passwd + (self.block_size - len(passwd) % self.block_size) * chr(
self.block_size - len(passwd) % self.block_size)
self.unpad = lambda passwd: passwd[:-ord(passwd[len(passwd) - 1:])]

def decrypt(self):
try:
signature = base64.b64decode(self.signature)
aes = AES.new(self.md5.digest(), AES.MODE_ECB)
return self.unpad(aes.decrypt(signature)).decode()
except Exception as e:
return None

def encrypt(self):
try:
aes = AES.new(self.md5.digest(), AES.MODE_ECB)
passwd = aes.encrypt(self.pad(self.signature))
return base64.b64encode(passwd)
except Exception as e:
return None


if __name__ == '__main__':
signature = 'FP7MsKoQifAW311/XPIzLQ=='
aes = AESDecryptDBPassWD('aaaaaaaa', signature)
password = aes.decrypt()
assert password == '123456'
print(password)