Qual é a melhor maneira de criptografar um clob?

Eu estou usando o Oracle 9 e JDBC e gostaria de encitar um clob como ele é inserido no banco de dados. Idealmente, gostaria de poder inserir o texto simples e criptografá-lo por um procedimento armazenado:

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

Não é esperado que o texto simples exceda 4000 caracteres, mas a criptografia torna o texto mais longo. Nossa abordagem atual para criptografia usa dbms_obfuscation_toolkit.DESEncrypt (), mas processamos apenas varchars. Será o seguinte trabalho?

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;

Estou confuso sobre o clob temporário; preciso fechar? Ou eu estou totalmente fora da pista?

Editar: O objetivo do ofuscamento é impedir o acesso trivial aos dados. Meu outro objetivo é ofuscar os clobs da mesma forma que já estamos ofuscando as colunas varchar. O código de amostra do oracle não lida com clobs, que é onde está meu problema específico; A encriptação de varchars (menor que 2000 caracteres) é simples.

0

3 Respostas

Há um exemplo na documentação do Oracle:

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

Você não precisa fechá-lo

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('>  ');
0
adicionado
Isso realmente não responde à pergunta; para um não usa o CLOBS e para dois não tem a mesma semântica que a função original: function crypt (plaintext in clob) retornando clob - retorna o texto do cypher
adicionado o autor Mr. Shiny and New 安宇, fonte

Um pouco fora do tópico: Qual é o objetivo da criptografia/ofuscação em primeiro lugar? Um invasor com acesso ao seu banco de dados poderá obter o texto simples - encontrar o procedimento armazenado acima permitirá que o invasor execute a descriptografia.

0
adicionado
O objetivo aqui é mais evitar que usuários com acesso autorizado revelem dados confidenciais acidentalmente.
adicionado o autor Mr. Shiny and New 安宇, fonte
Ter um backup com os dados não inscritos pode ser um problema de segurança. De qualquer forma, eu concordo que o documento irá viajar unencripted através da rede, mas para o efeito é melhor criptografar toda a conexão com https.
adicionado o autor borjab, fonte
A chave não deve ser armazenada em seu banco de dados, mas transmitida do aplicativo.
adicionado o autor Matthew Watson, fonte
Eu concordo com o comentário, mas o código original não está passando nenhuma chave para a função de criptografia.
adicionado o autor Alexander, fonte
Sysadmins decentes criptografam backups de qualquer maneira - você não precisa ter os dados do banco de dados criptografados para ter os backups do banco de dados criptografados. Parece aqui que o objetivo da criptografia aqui é impedir que os usuários que tenham acesso não autorizado ao banco de dados leiam os CLOBs.
adicionado o autor Alexander, fonte

Eu notei que você está no Oracle 9, mas apenas para o registro no Oracle 10g + o dbms_obfuscation_toolkit foi preterido em favor do dbms_crypto.

dbms_crypto does include CLOB support:

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