Imaginando el siguiente escenario: Cada usuario tiene una "palabra secreta" para desencriptar su propia información. En la base de datos todo se registra encriptado.
Para ello, Oracle ofrece dos paquetes:
- DBMS_OBFUSCATION_TOOLKIT. A partir de Oracle8i, que soporta encriptación DES y triple DES (Data Encription Standard), y con ciertas limitaciones (por ejemplo, los datos a encriptar han de ser un múltiplo de 8 bytes).
- DBMS_CRYPTO. A partir de Oracle10g. Soporta más formas de encriptación, como la AES (Advanced Encription Standard), que sustituye el anterior DES y no hay limitación con el número de carácteres.
Para mas información, la documentación de Oracle ofrece esta comparativa de funcionalidades.
Uso de DBMS_OBFUSCATION_TOOLKIT
El siguiente ejemplo muestra la encriptación de la palabra "SECRETO" (8 bytes) y genera un error al intentar encriptar "SECRETITOS!" (11 bytes)
SQL> select DBMS_OBFUSCATION_TOOLKIT.
DBMS_OBFUSCATION_TOOLKIT.
------------------------------
lr??
SQL> select DBMS_OBFUSCATION_TOOLKIT.
select DBMS_OBFUSCATION_TOOLKIT.
*
ERROR at line 1:
ORA-28232: invalid input length for obfuscation toolkit
ORA-06512: at "SYS.DBMS_OBFUSCATION_TOOLKIT_
ORA-06512: at "SYS.DBMS_OBFUSCATION_TOOLKIT"
El error ORA-28232 corresponde a la longitud inadecuada de la cadena a encriptar. 'SECRETITOS!" tiene 11 carácteres y el paquete está limitado a múltiplos de 8 bytes. Por ejemplo, el número de una tarjeta de crédito.
SQL> select DBMS_OBFUSCATION_TOOLKIT.DESEncrypt(input_string=>'1234567812345678',
2 key_string=>'clavedesencript')
3 from dual;
DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT(INPUT_STRING=>'1234567812345678',KEY_STRING=
--------------------------------------------------------------------------------
}??X??
De modo que la desencriptación funciona de igual modo, usando la función DESDecrypt
SQL> select DBMS_OBFUSCATION_TOOLKIT.
2 input_string=>DBMS_
3 key_string=>'CLAVE_BUENA') from dual;
DBMS_OBFUSCATION_TOOLKIT.
------------------------------
SECRETO!
SQL> select DBMS_OBFUSCATION_TOOLKIT.DESDecrypt(
2 input_string=>DBMS_OBFUSCATION_TOOLKIT.DESEncrypt(input_string=>'1111222233334444',key_string=>'CLAVE_BUENA'),
3 key_string=>'CLAVE_BUENA') from dual;
DBMS_OBFUSCATION_TOOLKIT.DESDECRYPT(INPUT_STRING=>DBMS_OBFUSCATION_TOOLKIT.DESEN
--------------------------------------------------------------------------------
1111222233334444
y si se utiliza una clave distinta, la información no se desencriptará adecuadamente.
SQL> select DBMS_OBFUSCATION_TOOLKIT.
2 input_string=>DBMS_
3 key_string=>'CLAVE_ERRONEA') from dual;
DBMS_OBFUSCATION_TOOLKIT.
------------------------------
???! k
...ó producirá un error.
SQL> select DBMS_OBFUSCATION_TOOLKIT.DESDecrypt(
2 input_string=>DBMS_OBFUSCATION_TOOLKIT.DESEncrypt(input_string=>'1111222233334444',key_string=>'CLAVE_BUENA'),
3 key_string=>'CLAVE_MALA') from dual;
ERROR:
ORA-29275: partial multibyte character
no rows selected
Uso de DBMS_CRYPTO
El siguiente ejemplo muestra la encriptación de la palabra "SECRETITOS!" (11 bytes) usando una suite de encriptación que ya viene implementada. En concreto es la DES_CBC_PCKS5, que contiene encriptación DES, encadenamiento de cifrado de bloques y modificadores de relleno PCKS5.
Es preciso, para invocar correctamente a este paquete, realizar una conversión a RAW de las cadenas a encriptar. He utilizado para ello el paquete UTL_RAW y la función UTL_I18N.STRING_TO_RAW.
SQL> select DBMS_CRYPTO.ENCRYPT(src => UTL_I18N.STRING_TO_RAW ('SECRETITOS!', 'AL32UTF8'),
2 typ => 4353,
3 key => UTL_I18N.STRING_TO_RAW ('clavedesencript', 'AL32UTF8')
4 )
5 from dual;
DBMS_CRYPTO.ENCRYPT(SRC=>UTL_
------------------------------
1BA7F933C2CAD0C7F4FDA685775BE0
Y la desencriptación de la información, con la función DECRYPT.
SQL> select UTL_RAW.cast_to_varchar2(
2 DBMS_CRYPTO.DECRYPT(
3 DBMS_CRYPTO.ENCRYPT(src => UTL_I18N.STRING_TO_RAW ('SECRETITOS!', 'AL32UTF8'),
4
5
6
7 typ => 4353,
8 key => UTL_I18N.STRING_TO_RAW ('clavedesdecript', 'AL32UTF8')
9 )
10 )
11 from dual;
UTL_RAW.CAST_TO_VARCHAR2(DBMS_
------------------------------
SECRETITOS!
Para más información sobre las múltiples formas de encriptación y uso de claves, lo mejor es consultar la documentación del paquete DBMS_CRYPTO.
12 comentarios:
Muchas gracias por tu ayuda!!!
Sigue así con este magnífico blog.
Un saludo
Gracias a ti, Sergio!
Un abrazo,
Hola Javier, Cordial Saludo. Excelente tu explicacion y gracias por ello. Tengo una inquietud: utilizando DBMS_CRYPTO puedo controlar la longitud de la cadana encriptada ? Cordialmente, Jesus Franco.
Hola Javier, gracias por tu ejemplo, es excelente. Tengo una inquietud al respecto, es posible controlar la longitud de la cadena encriptada que retorna DBMS_CRYPTO.ENCRYPT ? o como puedo determinar el largo de la cadana ecriptada. Gracias de nuevo. Jesus Franco
Hola Jesús,
El paquete de encriptación retorna un tipo RAW, que es de longitud fija.
:)
El uso de DBMS_CRYPTO requiere de una licencia adicional?
Hola Anónimo,
No hace falta licencia adicional. Es un paquete suministrado de PL/SQL como DBMS_OUTPUT o UTL_FILE.
Consulta con tu DBA si tienes algún problema al ejecutarlo, porque quizás tenga que concederte permisos para usarlo.
Un saludo
Hola Javier, se puede utilizar decode o case when en el where de un select,
select * from tabla1 where case when(tabla1.campo1=.t.) then ... else ... end
Hola William,
Si.
Doc. Oracle sobre Case.
Un saludo,
Javier
Perfecto,
es exactamente lo que estaba buscando. Y como seguimos utilizando Oracle 10 no hay ningún problema por que la entrada sea de hace cinco años ;-).
Saludos.
Hola Víctor!
Muchas gracias por tu comentario!
Solo añadir que el paquete DBMS_CRYPTO se sigue usando en Oracle12c! :)
Un saludo,
Javier
Publicar un comentario