Developpez.com

Une très vaste base de connaissances en informatique avec
plus de 100 FAQ et 10 000 réponses à vos questions

Developpez.com - Oracle
X

Choisissez d'abord la catégorieensuite la rubrique :


Cryptage des données dans Oracle 9i

Date de publication : le 16 Novembre 2006

Par Mohammed Bouayoun
 

Dans cet article, on décrit comment crypter les données dans une base Oracle 9i

I. Introduction
II. Remplissage et Chaînage
III. Cryptage des données
IV. Le vecteur d'initialisation
V. Décryptage de données
VI. Remerciements


I. Introduction

Le Cryptage, appelée également chiffrement, est un processus consistant à convertir des données de texte simple en texte crypté afin de les rendre incompréhensibles par un tiers non autorisé. Ce procédé se fait par le biais d'une clé de cryptage.

À partir de la 9i, Oracle fournit le paquetage DBMS_OBFUSCATION_TOOLKIT qui utilise seulement deux types de cryptages standards : DES et Triple DES.

info DES : Data Encryption Standard. Outil de cryptographie, mis au point par IBM dans les années 1970.
Le triple DES est basé sur une clé de 128 bytes et est plus robuste qu'un simple DES qui est basé sur une clé de 56 bytes.

warning Le DES 56 bits a été cassé en moins de 24 heures par Distributed.net, en janvier 1999. À la place du DES, NIST (novembre 2001) recommande l'utilisation de l'AES (Advanced Encryption Standard) qu'on va trouver dans le nouveau paquetage DBMS_CRYPTO (Oracle 10g).

II. Remplissage et Chaînage

Quand une chaîne de caractères est cryptée, elle est divisée en plusieurs morceaux de 8 bytes, qui sont traités indépendamment par l'algorithme de cryptage. Quand la longueur de données n'est pas un multiple de 8 bytes, l'algorithme ajoute quelques caractères à la fin pour l'amener exactement à 8 bytes. Ce processus est connu sous le nom de Remplissage (Padding).

Pour sécuriser la valeur de ce remplissage, on peut utiliser une méthode de remplissage pré-développée dans Oracle, connue sous le nom de PCKS#5 (Public Key Cryptography System), mais il existe d'autres options.

Quand une chaîne a été divisée en plusieurs morceaux, après, on doit ensuite les relier ensemble, ce processus est connu sous le nom de Chaînage (chaining). En général, la sécurité d'un système de cryptage est basée sur la manière d'enchaîner ces morceaux. Oracle fournit les méthodes suivantes :

Méthode Description
CBC Cipher Block Chaining, la méthode la plus utilisé
ECB Electronic Code Book
CFB Cipher Feedback
OFB Output Feedback

III. Cryptage des données

On va chiffrer le mot MOHAMMEDBOUAYOUN avec la clé ABCDEFGHIJKLMNOP
DECLARE
	   val_crypt VARCHAR2(200);
BEGIN
	DBMS_OBFUSCATION_TOOLKIT.des3encrypt
		(entree	=>	'MOHAMMEDBOUAYOUN',
		 cle		=>	'ABCDEFGHIJKLMNOP',
		 crypte => chif_val
		 );
	DBMS_OUTPUT.put_line('Valeur chiffrée = '|| val_crypt);
END;


Valeur chiffrée = â4u­¿Nc
ä§)^Sóq
Il peut être intéressant de stocker le résultat de la requête, pour par exemple l'imprimer. On peut également convertir cette valeur en un type de données RAW par le package UTL_RAW puis en Hexadécimal avec la fonction RAWTOHEX.

Ce qui donne :
DECLARE
	   val_chif VARCHAR2(200);
BEGIN
	DBMS_OBFUSCATION_TOOLKIT.des3encrypt
		(entree	=>	'MOHAMMEDBOUAYOUN',
		 cle		=>	'ABCDEFGHIJKLMNOP',
		 crypte => chif_val
		 );
	val_chif := RAWTOHEX(UTL_RAW.cast_to_raw(val_chif));
	DBMS_OUTPUT.put_line('Valeur chiffrée = '|| val_chif);
END;

Valeur chiffrée = E23475AD8A4E630A81E4A7295E53F371
On peut aussi convertir la valeur chiffrée de l'Hexadecimal en valeur numérique
val_chif := to_number('E23475AD8A4E630A81E4A7295E53F371','XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');

Valeur chiffré = 300677913275234235803498582057300521841
Dans les exemple précédents on a utilisé la fonction DES3ENCRYPT qui est un triple chiffrement DES. On peut utiliser d'autres fonctions.

Pour faciliter les choses, on crée la fonction :
CREATE OR REPLACE FUNCTION encrypte (p_entree IN VARCHAR2, p_cle IN VARCHAR2)
       RETURN VARCHAR2
    IS
       l_crypte   VARCHAR2 (200);
    BEGIN
       l_crypte :=
       DBMS_OBFUSCATION_TOOLKIT.des3encrypt (input_string      => p_entree,
                                             key_string        => p_cle
                                             );
       l_crypte := RAWTOHEX (UTL_RAW.cast_to_raw (l_crypte));
       RETURN l_crypte;
    END;

DECLARE
        v_crypte   VARCHAR2 (200);
     BEGIN
        v_crypte := encrypte ('MOHAMMEDBOUAYOUN', 'ABCDEFGHIJKLMNOP');
        DBMS_OUTPUT.put_line ('Valeur chiffrée= ' || v_crypte);
     END;
      /
Le resultat est :
Valeur chiffrée = E23475AD8A4E630A81E4A7295E53F371
Modifions la valeur à chiffrer MOHAMMEDBOUAYOUN par MOHAMMEDBOUAYOUN1.

Ceci nous donne le script suivant :
DECLARE
        v_crypte   VARCHAR2 (200);
     BEGIN
        v_crypte := encrypte ('MOHAMMEDBOUAYOUN1', 'ABCDEFGHIJKLMNOP');
        DBMS_OUTPUT.put_line ('Encrypted value = ' || v_crypte);
     END;
      /
En lançant le script précédent, on a l'erreur suivante :
ORA-28232: invalid input length for obfuscation toolkit
ORA-06512: at "SYS.DBMS_OBFUSCATION_TOOLKIT_FFI", line 0
ORA-06512: at "SYS.DBMS_OBFUSCATION_TOOLKIT", line 216
ORA-06512: at "SYSTEM.ENCRYPTE", line 6
ORA-06512: at line 4
On obtient cette erreur car l'entrée de la fonction DES3ENCRYPT doit être un multiple de 8 caractères, ce type de chiffrement est connu sous le nom de chiffrement par bloc (block ciphering). Pour remédier à ce problème, on écrit une autre fonction qui ajoute des espaces pour que la longueur de l'entrée soit un multiple de 8.
CREATE OR REPLACE FUNCTION encrypte (p_entree IN VARCHAR2, p_cle IN VARCHAR2)
       RETURN VARCHAR2
    IS
       l_crypte   VARCHAR2 (200);
	   l_entree	   VARCHAR2 (200);
    BEGIN
	   l_entree := RPAD(p_entree,(8*ROUND(LENGTH(p_entree)/8,0)+8));
       l_crypte :=
          DBMS_OBFUSCATION_TOOLKIT.des3encrypt (input_string      => l_entree,
                                                key_string        => p_cle
                                               );
       l_crypte := RAWTOHEX (UTL_RAW.cast_to_raw (l_crypte));
       RETURN l_crypte;
    END;

DECLARE
        v_crypte   VARCHAR2 (200);
     BEGIN
        v_crypte := encrypte ('MOHAMMEDBOUAYOUN1', 'ABCDEFGHIJKLMNOP');
        DBMS_OUTPUT.put_line ('Valeur chiffrée = ' || v_crypte);
     END;
      /
Le résultat est :
Valeur chiffrée = E23475AD8A4E630A81E4A7295E53F371DC94046D7D5747F8

IV. Le vecteur d'initialisation

Dans la méthode utilisée précédemment, un intrus peut utiliser un utilitaire de cryptoanalyse pour vérifier l'entête de l'information cryptée en identifiant le pattern. Pour éviter ceci, il est possible d'ajouter une valeur aléatoire au début la donnée en cours. Si par exemple, on a la valeur 12345678, on peut attacher au début la valeur 6564 qui devient 656412345678 puis l'encrypter après. L'entête de l'information contiendra des valeurs en relation avec 6564, et non pas avec la valeur en cours 12345678. Il ne faut pas oublier d'enlever la valeur aléatoire 6564 après le décryptage.

La valeur aléatoire préfixe au données est connu sous le nom vecteur d'initialisation (IV). Dans DBMS_OBFUSCATION_TOOLKIT, on spécifie ce vecteur d'initialisation dans la fonction DES3ENCRYPT comme un paramètre supplémentaire appelé iv_string. La combinaison de l'IV avec la donnée doit être un multiple de huit.
    CREATE OR REPLACE FUNCTION encrypte (
       p_entree   IN   VARCHAR2,
       p_cle      IN   VARCHAR2,
       p_iv       IN   VARCHAR2 := NULL
    )
       RETURN VARCHAR2
    IS
       l_crypte   VARCHAR2 (200);
       l_entree    VARCHAR2 (200);
       l_iv        VARCHAR2 (200);
    BEGIN
       l_entree := RPAD (p_entree, (8 * ROUND (LENGTH (p_entree) / 8, 0) + 8));
       l_iv := RPAD (p_iv, (8 * ROUND (LENGTH (p_iv) / 8, 0) + 8));
       l_crypte :=
          DBMS_OBFUSCATION_TOOLKIT.des3encrypt (input_string      => l_entree,
                                                key_string        => p_cle,
                                                iv_string         => l_iv
                                               );
       l_crypte := RAWTOHEX (UTL_RAW.cast_to_raw (l_crypte));
       RETURN l_crypte;
    END;

V. Décryptage de données

Maintenant, on va essayer de décrypter la valeur originale avec la fonction DES3DECRYPT. On créera une valeur cryptée depuis un texte clair et on le décryptera.
    DECLARE
       l_crypte   VARCHAR2 (2000);
       l_decrypte   VARCHAR2 (2000) := 'Clear Text Data';
       l_cle       VARCHAR2 (2000) := 'ABCDEFGHIJKLMNOP';
    BEGIN
       l_crypte := get_enc_val (l_decrypte, l_cle, '12345678');
       l_decrypte :=
          DBMS_OBFUSCATION_TOOLKIT.des3decrypt
                  (input_string      => UTL_RAW.cast_to_varchar2
                                                              (HEXTORAW (l_crypte)
                                                              ),
                   key_string        => l_cle
                  );
       DBMS_OUTPUT.put_line ('Valeur décryptée = ' || l_decrypte);
    END;
    /
Le résultat est différent de la valeur originale !

Tout simplement, on doit spécifier l'IV pendant le décryptage qui était 12345678.
DECLARE
       l_crypte   VARCHAR2 (2000);
       l_decrypte   VARCHAR2 (2000) := 'Clear Text Data';
       l_cle       VARCHAR2 (2000) := 'ABCDEFGHIJKLMNOP';
    BEGIN
       l_enc_val := encrypte (l_decrypte, l_cle, '12345678');
       l_decrypte :=
          DBMS_OBFUSCATION_TOOLKIT.des3decrypt
                  (input_string      => UTL_RAW.cast_to_varchar2
                                                              (HEXTORAW (l_crypte)
                                                              ),
                   key_string        => l_cle,
                   iv_string         => '12345678'
                  );
       DBMS_OUTPUT.put_line ('Valeur Décryptée = ' || l_decrypte);
    END;
    /
Le résultat est :
Valeur Décryptée = Clear Text Data

    PL/SQL procedure successfully completed.

VI. Remerciements

Je tiens à remercier toute l'équipe de Developpez.com pour son aide dans la relecture et l'amélioration du présent tutoriel, en particulier Xo pour la correction de l'orthographe.



Valid XHTML 1.1!Valid CSS!

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
Contacter le responsable de la rubrique Oracle