Plagiado.

Alguien llamado Fernando Valenzuela me ha plagiado unos siete artículos.
En la mayoría ni siquiera ha cambiado la tipografía, ni los datos de ejemplo, ni comentarios personales como dedicatorias o alusiones a las personas que motivaron la creación de esa entrada, o los responsables de las peticiones o consultas.
Me parece algo muy grave, sobre todo teniendo en cuenta que todo el contenido que hay publicado en mi blog está bajo una licencia creativa (Creative Commons) que permite prácticamente cualquier uso de mi trabajo, o incluso hacer obras derivadas, siempre y cuando se reconozca al autor, y se publique bajo una licencia similar sin provecho comercial.
En concreto, los artículos plagiados son:

Copiar una Base de datos en Windows
Original creado el 29 de Julio de 2005, y plagiado el 31 de agosto de 2009

Acceso a una bbdd MSAccess desde Oracle
Original creado el 8 de Septiembre de 2006 y plagiado el 31 de agosto de 2009

Uso de Logminer
Original creado el 21 de Marzo de 2006 y plagiado el 31 de agosto de 2009

Optimización SQL – varios artículos
Original creados el 25 de Octubre de 2005, el 17 de Octubre de 2005 , el 13 de Octubre de 2005 , y el 11 de Octubre de 2005, y plagiados el 31 de agosto de 2009 aquí y aquí.

Encriptación de datos desde aplicación.

En todos los ejemplos que he encontrado sobre encriptación y desencriptación de datos en Oracle, siempre se usan procedimientos PL/SQL para establecer la seguridad en la base de datos. No he encontrado un sólo ejemplo que permita hacer un insert «encriptado» y una consulta «desencriptada».

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.DESEncrypt(input_string=>SECRETO!’,key_string=>’clavedesencript’) from dual;

DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT(INPUT_STRING=>’SECRETO!’,KEY_STRING=>’CLAVED
——————————————————————————–
lr??

SQL> select DBMS_OBFUSCATION_TOOLKIT.DESEncrypt(input_string=>SECRETITOS!’,key_string=>’clavedesencript’) from dual;
select DBMS_OBFUSCATION_TOOLKIT.DESEncrypt(input_string=>’SECRETITOS!’,key_string=>’clavedesencript’) from dual
*
ERROR at line 1:
ORA-28232: invalid input length for obfuscation toolkit
ORA-06512: at «SYS.DBMS_OBFUSCATION_TOOLKIT_FFI», line 21
ORA-06512: at «SYS.DBMS_OBFUSCATION_TOOLKIT», line 126

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.DESDecrypt(
2 input_string=>DBMS_OBFUSCATION_TOOLKIT.DESEncrypt(input_string=>’SECRETO!’,key_string=>’CLAVE_BUENA’),
3 key_string=>’CLAVE_BUENA’) from dual;

DBMS_OBFUSCATION_TOOLKIT.DESDECRYPT(INPUT_STRING=>DBMS_OBFUSCATION_TOOLKIT.DESEN
——————————————————————————–
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.DESDecrypt(
2 input_string=>DBMS_OBFUSCATION_TOOLKIT.DESEncrypt(input_string=>’SECRETO!’,key_string=>’CLAVE_BUENA’),
3 key_string=>’CLAVE_ERRONEA’) from dual;

DBMS_OBFUSCATION_TOOLKIT.DESDECRYPT(INPUT_STRING=>DBMS_OBFUSCATION_TOOLKIT.DESEN
——————————————————————————–
???! 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_I18N.STRING_TO_RAW(‘SECRETITOS!’,’AL32UTF8′),TYP=>4
——————————————————————————–
1BA7F933C2CAD0C7F4FDA685775BE0E7

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 typ => 4353,
5 key => UTL_I18N.STRING_TO_RAW (‘clavedesencript’, ‘AL32UTF8’)
6 ),
7 typ => 4353,
8 key => UTL_I18N.STRING_TO_RAW (‘clavedesdecript’, ‘AL32UTF8’)
9 )
10 )
11 from dual;

UTL_RAW.CAST_TO_VARCHAR2(DBMS_CRYPTO.DECRYPT(DBMS_CRYPTO.ENCRYPT(SRC=>UTL_I18N.S
——————————————————————————–
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.

Oracle10g Data Miner.

Una de las cosas más interesantes en la explotación de una base de datos es, finalmente, la minería de éstos.

El concepto de «minería de datos» se basa en el análisis de los datos con fines predictivos, para encontrar patrones ocultos en éstos… ¿quien podría adivinar que a una determinada hora o un determinado día de la semana se consume un determinado producto? ¿o que un producto orientado a hombres (cuchillas de afeitar) pasa a ser usado por mujeres solteras de un rango de edad?

Una predicción de este tipo podría sugerir la creación de una nueva linea de producto, ofertas, etc.

Hace tiempo impartí una conferencia sobre cómo implementar un modelo de base de datos de reservas en vuelos, desde un diagrama entidad-relación concreto hasta la explotación de datos históricos en el futuro. La aplicación pasaba por varias etapas (diseño, implementación, uso/cargas de datos, paso a histórico y reporting), y aunque los datos eran cargas completamente aleatorias, sucedían ciertos patrones interesantes.

Los casados tomaban vuelos a Roma, los solteros a Milán, «Air France» viajaba con los vuelos a medio llenar, y otras compañías apenas tenían uno o dos vuelos con pérdidas…

De modo que se me ocurrió hacer una prueba de minería de datos, para buscar una predicción que no pudiera verse «a simple vista». Éste fue el resultado:

Ejemplo de Uso – Oracle Data Miner – Parte 1/2

Ejemplo de Uso – Oracle Data Miner – Parte 2/2

Al final, la predicción (absurda) sobre los datos aleatorios fue una relación de probabilidades en las cuales un determinado tipo de persona (hombre/mujer, de una edad, de una ciudad) reservaría billetes con precios superiores a la media.