使用 DBMS_CRYPTO 但使用 dbms_obfuscation_toolkit 时出错

Posted

技术标签:

【中文标题】使用 DBMS_CRYPTO 但使用 dbms_obfuscation_toolkit 时出错【英文标题】:Error while using DBMS_CRYPTO but working with dbms_obfuscation_toolkit 【发布时间】:2019-06-13 07:07:10 【问题描述】:

捕获的 SQLException :: java.sql.SQLException: ORA-29532: Java 调用因未捕获的 Java 异常而终止: java.sql.SQLException: 无法获取服务器访问帐户详细信息: ORA-28817: PL/SQL 函数返回错误.

ORA-06512:在“SYS.DBMS_CRYPTO_FFI”,第 67 行

ORA-06512:在“SYS.DBMS_CRYPTO”,第 44 行

ORA-06512:在“NM.CIPHER”,第 41 行

ORA-06512:在“NM.DEVICE_ACCOUNT”,第 176 行

ORA-06512:在第 1 行

ORA-06512:在“NM.DEVICE_PROCEDURES”,第 8 行

ORA-06512:在第 1 行


开发代码

create or replace PACKAGE BODY CIPHER IS
seven_bytes RAW(7) := HEXTORAW ('00000000000000');

FUNCTION    make_8_bytes (  p_string    IN  RAW ) RETURN RAW IS
    v_length    PLS_INTEGER := MOD(utl_raw.length (p_string),8);
BEGIN
    IF v_length = 0 THEN
        RETURN p_string;
    ELSE
        RETURN utl_raw.concat (p_string,utl_raw.substr(seven_bytes,1,8-v_length));
    END IF;
END;




FUNCTION    encrypt (   p_string    IN  VARCHAR2,
                                        p_key   IN  RAW  ) RETURN RAW IS
    encrypted_raw   RAW(2048);
    l_mod number := dbms_crypto.ENCRYPT_DES
                    + dbms_crypto.CHAIN_CBC
                    + dbms_crypto.PAD_PKCS5;

BEGIN
    --dbms_obfuscation_toolkit.DESEncrypt(input => make_8_bytes (utl_raw.cast_to_raw(p_string)),key => make_8_bytes (p_key), encrypted_data => encrypted_raw );
      encrypted_raw:= dbms_crypto.encrypt(src => make_8_bytes (utl_raw.cast_to_raw(p_string)),typ => l_mod, key => make_8_bytes (p_key));

    RETURN  encrypted_raw;
    
     EXCEPTION                
       WHEN OTHERS THEN 
                v_errm:=SUBSTR(SQLERRM,1,200);
END;


FUNCTION    decrypt (   p_string    IN  RAW,
                                        p_key   IN  RAW  ) RETURN VARCHAR2 IS
    decrypted_raw   RAW(2048);
    l_ret varchar2 (2000);
    l_mod number := dbms_crypto.ENCRYPT_DES
                    + dbms_crypto.CHAIN_CBC
                    + dbms_crypto.PAD_PKCS5;

BEGIN
       -- dbms_obfuscation_toolkit.DESDecrypt(input => p_string,key => make_8_bytes (p_key), decrypted_data => decrypted_raw );
        decrypted_raw:= dbms_crypto.Decrypt(src => p_string,typ => l_mod,key => make_8_bytes (p_key));
        l_ret:= UTL_I18N.RAW_TO_CHAR(decrypted_raw, 'AL32UTF8');
        RETURN l_ret;
    --RETURN rtrim(utl_raw.cast_to_varchar2(decrypted_raw),chr(0));
    
     EXCEPTION                
       WHEN OTHERS THEN 
                v_errm:=SUBSTR(SQLERRM,1,200);
END;
END CIPHER;
 

【问题讨论】:

这和Java有什么关系? 如何发布full错误堆栈,以便我们可以看到real错误信息? 【参考方案1】:

我试过你的代码,结果是肯定的。

当我对 ENCRYPT 和 DECRYPT 使用不同的密钥时会引发错误。

请看下面的例子:

ENCRYPT 和 DECRYPT 使用相同的密钥:

SELECT
    CIPHER.DECRYPT(CIPHER.ENCRYPT('***', UTL_RAW.CAST_TO_RAW('123')), UTL_RAW.CAST_TO_RAW('123'))
FROM
    DUAL;

ENCRYPT 和 DECRYPT 的不同密钥:

SELECT
    CIPHER.DECRYPT(CIPHER.ENCRYPT('***', UTL_RAW.CAST_TO_RAW('123')), UTL_RAW.CAST_TO_RAW('1234'))
FROM
    DUAL;

【讨论】:

我还有一个问题。我认为错误可能是由于数据库中使用 dbms_obfuscation_toolkit.DESEncrypt 加密的先前数据而出现的,这些数据是 dbms_crypto 无法解密并因此引发此错误。我尝试使用以下 select 语句对现有加密数据进行一些数据提升 ...update SNMPV3_PARAMETER_values set value = (cipher.newencrypt(cipher.decrypt(VALUE,'2FADE7CB910B9C01'),'2FADE7CB910B9C01')) 其中 pn_id = 5 并且值为不为空;但是在使用 dbms_crypto.decrypt 时,我得到了一些带有原始文本的垃圾值 123 之类的值已成功加密和解密尝试现实生活中的一些东西;)【参考方案2】:

当我使用 UTL_RAW 转换为 RAW 时,有时会遇到同样的错误。这取决于价值。

关于ORA-06512: at "SYS.DBMS_CRYPTO_FFI", line 67-error Oracle 支持建议仅使用RAWTOHEXUTL_ENCODE.BASE64_ENCODE 函数来传递值以进行解密或存储。分别是HEXTORAWUTL_ENCODE.BASE64_DECODE

【讨论】:

以上是关于使用 DBMS_CRYPTO 但使用 dbms_obfuscation_toolkit 时出错的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL/SQL dbms_crypto 包可以解密使用 Linux gpg 命令加密的文件吗?

Oracle DBMS_CRYPTO.ENCRYPT AES256 的初始化向量长度

Oracle 加解密教程

Oraclesqlplus中的set设置

plsql实现DES对称加密

将 Oracle PL/SQL 代码转换为 C#