¿Cuál es la mejor manera de encriptar un clob?

Estoy usando Oracle 9 y JDBC y me gustaría encyrpt un clob ya que se inserta en la base de datos. Idealmente, me gustaría poder insertar el texto plano y cifrarlo mediante un procedimiento almacenado:

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

No se espera que el texto en claro exceda los 4000 caracteres, pero el cifrado hace que el texto sea más largo. Nuestro enfoque actual para el cifrado utiliza dbms_obfuscation_toolkit.DESEncrypt() pero solo procesamos varchar. ¿Funcionará lo siguiente?

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;

Estoy confundido sobre el clob temporal; ¿Necesito cerrarlo? ¿O estoy totalmente fuera de la pista?

Editar: El propósito de la ofuscación es evitar el acceso trivial a los datos. Mi otro propósito es ofuscar las manchas de la misma manera que ya estamos ofuscando las columnas varchar. El código de muestra de Oracle no trata con clobs, que es donde reside mi problema específico; varchar de encriptación (más de 2000 caracteres) es sencillo.

0

3 Respuestas

Hay un ejemplo en la Documentación de Oracle:

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

No necesitas cerrarlo

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
agregado
Esto realmente no responde la pregunta; para uno no usa CLOBS y para dos no tiene la misma semántica que la función original: función de cifrado (texto sin formato en clob) return clob - devuelve texto de cifrado
agregado el autor Mr. Shiny and New 安宇, fuente

Un poco fuera de tema: ¿Cuál es el objetivo de la encriptación/ofuscación en primer lugar? Un atacante que tenga acceso a su base de datos podrá obtener el texto sin formato. Encontrar el procedimiento almacenado anterior permitirá al atacante realizar el descifrado.

0
agregado
El objetivo aquí es más para evitar que los usuarios con acceso autorizado revelen accidentalmente datos confidenciales.
agregado el autor Mr. Shiny and New 安宇, fuente
Tener una copia de seguridad con los datos sin encriptar puede ser un problema de seguridad. De todos modos, estoy de acuerdo en que el documento viajará sin encriptar a través de la red, pero para ese propósito es mejor encriptar toda la conexión con https.
agregado el autor borjab, fuente
La clave no debe almacenarse en su base de datos, sino que debe pasarla desde la aplicación.
agregado el autor Matthew Watson, fuente
Estoy de acuerdo con el comentario, pero el código original no está pasando ninguna clave a la función de cifrado.
agregado el autor Alexander, fuente
Los administradores de sistemas decentes encriptan las copias de seguridad de todos modos: no es necesario cifrar los datos de la base de datos para que se cifren las copias de seguridad de la base de datos. Aquí parece que el objetivo del cifrado es evitar que los usuarios que tienen acceso no autorizado a la base de datos lean los CLOB.
agregado el autor Alexander, fuente

Noto que está en Oracle 9, pero solo para el registro en Oracle 10g + el dbms_obfuscation_toolkit fue desaprobado a favor de 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
agregado