如何最好地加密CLOB?

3

我正在使用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列相同的方式混淆clobs。Oracle示例代码没有处理clobs,这就是我的具体问题所在;加密小于2000个字符的varchars()是简单明了的。

3个回答

2

在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,其次它的语义与原始函数不同: function encrypt (plaintext in clob) returning clob -- 返回密文 - Mr. Shiny and New 安宇

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);

1
略微偏题:加密/混淆的目的是什么?攻击者如果能够访问您的数据库,将能够获取明文——找到上述存储过程将使攻击者能够执行解密。

密钥不应存储在您的数据库中,而应从应用程序传递。 - Matthew Watson
我同意评论,但原始代码没有将任何密钥传递给加密函数。 - Alexander
拥有未加密数据的备份可能会成为安全问题。无论如何,我同意文档将在网络上以未加密的方式传输,但为此最好使用https加密整个连接。 - borjab
体面的系统管理员无论如何都会加密备份 -- 您不需要对数据库数据进行加密,就可以对数据库备份进行加密。这里加密的目标似乎是为了防止用户未经授权访问数据库并读取CLOBs。 - Alexander
这里的目标更多是防止具有授权访问权限的用户意外泄露敏感数据。 - Mr. Shiny and New 安宇

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接