Pregunta

Estoy usando Oracle 9 y JDBC y me gustaría cifrar un clob a medida que se inserta en la base de datos.Idealmente, me gustaría poder simplemente insertar el texto sin formato 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 plano supere los 4000 caracteres, pero el cifrado alarga el texto.Nuestro enfoque actual de cifrado utiliza dbms_obfuscation_toolkit.DESEncrypt() pero solo procesamos varchars.¿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 acerca del golpe temporal;¿Necesito cerrarlo?¿O estoy totalmente desviado?

Editar:El propósito de la ofuscación es evitar el acceso trivial a los datos.Mi otro propósito es ofuscar los clobs 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 radica mi problema específico;cifrar varchars (menos de 2000 caracteres) es sencillo.

¿Fue útil?

Solución

Observo que está en Oracle 9, pero solo para que conste en Oracle 10g+, dbms_obfuscation_toolkit quedó obsoleto en favor de dbms_crypto.

dbms_crypto incluye soporte 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);

Otros consejos

Hay un ejemplo en la documentación de Oracle:

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

No es necesario 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('>  ');

Ligeramente fuera de tema:¿Cuál es el punto del cifrado/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 le permitirá al atacante realizar el descifrado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top