Sauvgarde de mot de passe dans une base de donnée Oracle
Quand on parle de gestion de la sécurité des applications,il y'a souvent un besoin de stocker des mots de passe
dans une table de base de données. Ceci peut en soi mener aux questions de sécurité, puisque des utilisateurs
avec des privilèges appropriés peuvent lire le contenu des ces tables . Une approche de sécurité consiste en
le cryptage des mots de passe avant leurs stockages,mais un mécanisme de décryptage pourrait vous exposer a une
faille de sécurité. Une alternative plus sûr est de stocker le hash code du nom utilisateur et de son mot de passe
comme mot passe de sécurité.Dans cette article, je vous montre un processus utilisant le package DBMS_OBFUSCATION_TOOLKIT
qui est disponible sur Oracle9i ou bien en sha_1 avec Oracle 10
Premiérement on va crée une table pour sauvgarder le nom utilisateur et sont mot de passe.
Example
|
> SQLPLUS scott/tiger
Oracle Database 10g Release 10.2.0.1.0 - Production
SQL> SET LINESIZE 130
SQL> CREATE TABLE demo_users (
id_user NUMBER(12) NOT NULL,
username VARCHAR2(128) NOT NULL,
password VARCHAR2(128) NOT NULL
);
SQL> Table created.
SQL>ALTER TABLE demo_users ADD (
CONSTRAINT id_users_pk PRIMARY KEY (id_user)
);
SQL> Table altered.
SQL>ALTER TABLE demo_users ADD (
CONSTRAINT users_name_uk UNIQUE (username)
);
SQL> Table altered.
SQL>CREATE SEQUENCE demo_users_seq;
SQL> sequence created.
--Création du package pour la sécurisation des informations des utilisateur
SQL> CREATE OR REPLACE PACKAGE demo_user_security AS
FUNCTION GET_HASH (p_username IN VARCHAR2,
p_password IN VARCHAR2)
RETURN VARCHAR2;
PROCEDURE add_user (p_username IN VARCHAR2,
p_password IN VARCHAR2);
PROCEDURE change_password (p_username IN VARCHAR2,
p_old_password IN VARCHAR2,
p_new_password IN VARCHAR2);
PROCEDURE valid_user (p_username IN VARCHAR2,
p_password IN VARCHAR2);
FUNCTION valid_user (p_username IN VARCHAR2,
p_password IN VARCHAR2)
RETURN BOOLEAN;
END;
SQL> package created.
SQL>CREATE OR REPLACE PACKAGE BODY demo_user_security AS
FUNCTION GET_HASH (p_username IN VARCHAR2,
p_password IN VARCHAR2)
RETURN VARCHAR2 AS
v_secur VARCHAR2(30) := 'Test';
BEGIN
-- Pre Oracle 10g
RETURN DBMS_OBFUSCATION_TOOLKIT.MD5(
input_string => UPPER(p_username) || v_secur || UPPER(p_password));
-- Oracle 10g+ : Require EXECUTE on DBMS_CRYPTO
--RETURN DBMS_CRYPTO.HASH(UTL_RAW.CAST_TO_RAW(UPPER(p_username)
--|| v_secur || UPPER(p_password)),DBMS_CRYPTO.HASH_SH1);
END;
PROCEDURE add_user (p_username IN VARCHAR2,
p_password IN VARCHAR2) AS
BEGIN
INSERT INTO demo_users (
id_user,
username,
password
)
VALUES (
demo_users_seq.NEXTVAL,
UPPER(p_username),
GET_HASH(p_username, p_password)
);
COMMIT;
END;
PROCEDURE change_password (p_username IN VARCHAR2,
p_old_password IN VARCHAR2,
p_new_password IN VARCHAR2) AS
v_rowid ROWID;
BEGIN
SELECT rowid
INTO v_rowid
FROM demo_users
WHERE username = UPPER(p_username)
AND password = get_hash(p_username, p_old_password)
FOR UPDATE;
UPDATE demo_users
SET password = get_hash(p_username, p_new_password)
WHERE rowid = v_rowid;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20010, 'nom utilisateur/mot de passe incorrect.');
END;
PROCEDURE valid_user (p_username IN VARCHAR2,
p_password IN VARCHAR2) AS
v_numy VARCHAR2(1);
BEGIN
SELECT '1'
INTO v_numy
FROM demo_users
WHERE username = UPPER(p_username)
AND password = get_hash(p_username, p_password);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000, 'nom utilisateur/mot de passe incorrect.');
END;
FUNCTION valid_user (p_username IN VARCHAR2,
p_password IN VARCHAR2)
RETURN BOOLEAN AS
BEGIN
valid_user(p_username, p_password);
RETURN TRUE;
EXCEPTION
WHEN OTHERS THEN
RETURN FALSE;
END;
END;
/
SQL> package body created.
|
La surcharge de VALID_USER permet un contrôle de sécurité de façon différente.La fonction de GET_HASH est
utilisée pour hacher la combinaison du nom d'utilisateur et du mot de passe. Il rend toujours un VARCHAR2
indépendamment de la longueur des paramètres de saisie.DBMS_OBFUSCATION_TOOLKIT.MD5 permet de vous générer un
hash code en MD5.
|
--Exemple:
--Création des utilisateurs
SQL> exec demo_user_security.add_user('Smith','secret');
PL/SQL procedure successfully completed.
SQL> exec demo_user_security.add_user('William','terces121');
PL/SQL procedure successfully completed.
SQL> select * from demo_users;
ID USERNAME PASSWORD
----------- -----------------------------------------------
1 Smith ãXFõˆC„®W3–E
2 William b¾õmûMÀ*愶}ˆ
--Ensuite on va vérifier la procédure VALID_USER
SQL> EXEC demo_user_security.valid_user('Smith','secret');
PL/SQL procedure successfully completed.
SQL> EXEC demo_user_security.valid_user('William','bblsld');
BEGIN app_user_security.valid_user('william','bblsld'); END;
*
ERROR at line 1:
ORA-20000: nom utilisateur/mot de passe incorrect.
ORA-06512: at "W2K1.DEMO_USER_SECURITY", line 66
ORA-06512: at line 1
--Ensuite on vérifiéra la fonction VALID_USER.
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
2 IF demo_user_security.valid_user('Smith','secret') THEN
3 DBMS_OUTPUT.PUT_LINE('TRUE');
4 ELSE
5 DBMS_OUTPUT.PUT_LINE('FALSE');
6 END IF;
7 END;
8 /
TRUE
PL/SQL procedure successfully completed.
SQL> BEGIN
2 IF demo_user_security.valid_user('William','bblsld') THEN
3 DBMS_OUTPUT.PUT_LINE('TRUE');
4 ELSE
5 DBMS_OUTPUT.PUT_LINE('FALSE');
6 END IF;
7 END;
8 /
FALSE
PL/SQL procedure successfully completed.
SQL>
--Au final on vérifiéra la procédure CHANGE_PASSWORD.
SQL> exec demo_user_security.change_password('Smith','secret','tresect');
PL/SQL procedure successfully completed.
SQL> exec demo_user_security.change_password('William','vfrdtg','vcftg12');
BEGIN app_user_security.change_password('William','vfrdtg','vfrd14g'); END;
*
ERROR at line 1:
ORA-20000: nom utilisateur/mot de passe incorrect.
ORA-06512: at "W2K1.DEMO_USER_SECURITY", line 52
ORA-06512: at line 1
|