I. Introduction▲
Le Cryptage, appelé é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.
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.
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
\x81ä§)^
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ée =
300677913275234235803498582057300521841
Dans les exemples 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 résultat 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 aux 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.