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(4000)    := utl_raw.cast_to_raw(
                sys.dbms_obfuscation_toolkit.md5(input_string => I_KEY_STRING)); -- 加密串,同时也是解密串
        V_ENCRYPTED_RAW RAW(4000);
        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(4000)    := utl_raw.cast_to_raw(
                sys.dbms_obfuscation_toolkit.md5(input_string => I_KEY_STRING));-- 加密串,同时也是解密串
        V_DECRYPTED_RAW RAW(4000);
        b64_de          RAW(4000);
        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
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)
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计