【问题标题】:What is the best way to encrypt a clob?加密 clob 的最佳方法是什么?
【发布时间】:2010-09-10 22:47:07
【问题描述】:

我正在使用 Oracle 9 和 JDBC,并希望在将 clob 插入数据库时​​对其进行加密。理想情况下,我希望能够插入明文并通过存储过程对其进行加密:

String SQL = "INSERT INTO table (ID, VALUE) values (?, encrypt(?))";
PreparedStatement ps = connection.prepareStatement(SQL);
ps.setInt(id);
ps.setString(plaintext);
ps.executeUpdate();

明文预计不会超过 4000 个字符,但加密会使文本更长。我们当前的加密方法使用 dbms_obfuscation_toolkit.DESEncrypt() 但我们只处理 varchars。以下是否可行?

FUNCTION encrypt(p_clob IN CLOB) RETURN CLOB
IS
    encrypted_string        CLOB;
    v_string                CLOB;
BEGIN
  dbms_lob.createtemporary(encrypted_string, TRUE);
  v_string := p_clob;
  dbms_obfuscation_toolkit.DESEncrypt(
    input_string => v_string,
    key_string => key_string,
    encrypted_string => encrypted_string );
  RETURN UTL_RAW.CAST_TO_RAW(encrypted_string);
END;

我对临时的 clob 感到困惑;我需要关闭它吗?还是我完全偏离了轨道?

编辑: 混淆的目的是防止对数据的琐碎访问。我的另一个目的是以与我们已经混淆 varchar 列相同的方式混淆 clob。 oracle 示例代码不处理我的具体问题所在的 clob;加密 varchars(小于 2000 个字符)很简单。

【问题讨论】:

    标签: java oracle encryption jdbc plsql


    【解决方案1】:

    我注意到您使用的是 Oracle 9,但只是为了记录在 Oracle 10g+ 中,dbms_obfuscation_toolkit 已被弃用,取而代之的是 dbms_crypto。

    dbms_crypto 确实包含 CLOB 支持:

    DBMS_CRYPTO.ENCRYPT(
       dst IN OUT NOCOPY BLOB,
       src IN            CLOB         CHARACTER SET ANY_CS,
       typ IN            PLS_INTEGER,
       key IN            RAW,
           iv  IN            RAW          DEFAULT NULL);
    
    DBMS_CRYPT.DECRYPT(
       dst IN OUT NOCOPY CLOB         CHARACTER SET ANY_CS,
       src IN            BLOB,
       typ IN            PLS_INTEGER,
       key IN            RAW,
       iv  IN            RAW          DEFAULT NULL);
    

    【讨论】:

      【解决方案2】:

      有点题外话:首先加密/混淆有什​​么意义?有权访问您的数据库的攻击者将能够获得明文——找到上述存储过程将使攻击者能够执行解密。

      【讨论】:

      • 密钥不应存储在您的数据库中,而应从应用程序传入。
      • 我同意评论,但原始代码没有将任何密钥传递给加密函数。
      • 使用未加密的数据进行备份可能是一个安全问题。无论如何,我同意该文档将通过网络未经加密传输,但为此目的,最好使用 https 加密整个连接。
      • 体面的系统管理员无论如何都会加密备份——你不需要加密数据库数据来加密数据库的备份。看来这里加密的目的是防止未经授权访问数据库的用户读取 CLOB。
      • 这里的目标更多是为了防止具有授权访问权限的用户意外泄露敏感数据。
      【解决方案3】:

      Oracle 文档中有一个示例:

      http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_obtoo2.htm

      你不需要关闭它

      DECLARE
         input_string        VARCHAR2(16) := 'tigertigertigert';
         raw_input           RAW(128) := UTL_RAW.CAST_TO_RAW(input_string);
         key_string          VARCHAR2(8)  := 'scottsco';
         raw_key             RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
         encrypted_raw               RAW(2048);
         encrypted_string            VARCHAR2(2048);
         decrypted_raw               RAW(2048);
         decrypted_string            VARCHAR2(2048); 
         error_in_input_buffer_length EXCEPTION;
         PRAGMA EXCEPTION_INIT(error_in_input_buffer_length, -28232);
         INPUT_BUFFER_LENGTH_ERR_MSG VARCHAR2(100) :=
          '*** DES INPUT BUFFER NOT A MULTIPLE OF 8 BYTES - IGNORING 
      EXCEPTION ***';
         double_encrypt_not_permitted EXCEPTION;
         PRAGMA EXCEPTION_INIT(double_encrypt_not_permitted, -28233);
         DOUBLE_ENCRYPTION_ERR_MSG VARCHAR2(100) :=
          '*** CANNOT DOUBLE ENCRYPT DATA - IGNORING EXCEPTION ***';
      
          -- 1. Begin testing raw data encryption and decryption
             BEGIN
         dbms_output.put_line('> ========= BEGIN TEST RAW DATA =========');
         dbms_output.put_line('> Raw input                        : ' || 
                   UTL_RAW.CAST_TO_VARCHAR2(raw_input));
         BEGIN 
            dbms_obfuscation_toolkit.DESEncrypt(input => raw_input, 
                     key => raw_key, encrypted_data => encrypted_raw );
            dbms_output.put_line('> encrypted hex value              : ' || 
                 rawtohex(encrypted_raw));
        dbms_obfuscation_toolkit.DESDecrypt(input => encrypted_raw, 
                 key => raw_key, decrypted_data => decrypted_raw);
        dbms_output.put_line('> Decrypted raw output             : ' || 
                      UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw));
        dbms_output.put_line('>  ');      
        if UTL_RAW.CAST_TO_VARCHAR2(raw_input) = 
                      UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw) THEN
           dbms_output.put_line('> Raw DES Encyption and Decryption successful');
        END if;
         EXCEPTION
            WHEN error_in_input_buffer_length THEN
                   dbms_output.put_line('> ' || INPUT_BUFFER_LENGTH_ERR_MSG);
         END;
         dbms_output.put_line('>  ');
      

      【讨论】:

      • 这并不能真正回答问题;一方面它不使用 CLOBS,另一方面它没有与原始函数相同的语义:函数 encrypt (plaintext in clob) 返回 clob -- 返回密码文本
      猜你喜欢
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 2022-01-25
      • 2012-12-29
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多