資料庫中儲存敏感資料(如密碼)時,明文儲存極具風險。MD5 作為單向雜湊演算法,雖已不建議用於高安全性場景,但在舊系統相容或低敏感度資料保護上仍常見。Oracle 內建 DBMS_OBFUSCATION_TOOLKIT 套件提供 MD5 運算功能,本文示範如何封裝為可重複使用的 PL/SQL 套件。
create or replace package test_md5 as
function fn_getmd5(p_str in varchar2) return varchar2;
function fn_checkuser(p_username in varchar2, p_password in varchar2) return number;
end;
/
create or replace package body test_md5 as
function fn_getmd5(p_str in varchar2) return varchar2 as
begin
-- 輸入轉大寫後計算 MD5,回傳 RAW,隱性轉為 VARCHAR2
return DBMS_OBFUSCATION_TOOLKIT.MD5(input_string => Upper(p_str));
end;
function fn_checkuser(p_username in varchar2, p_password in varchar2) return number is
l_password varchar2(1000);
begin
select password into l_password
from test_user
where upper(username) = upper(p_username)
and password = test_md5.fn_getmd5(p_password);
if l_password is null then
return 0; -- 密碼錯誤
else
return 1; -- 驗證成功
end if;
exception
when NO_DATA_FOUND then
return 3; -- 使用者不存在
end;
end;
/
-- 清空並建立測試資料
delete from test_user;
insert into test_user values('A', test_md5.fn_getmd5('aa'));
insert into test_user values('B', test_md5.fn_getmd5('bb'));
commit;
-- 查看儲存的雜湊值
select * from test_user;
-- 驗證登入
select test_md5.fn_checkuser('a','aa') from dual; -- 回傳 1
select test_md5.fn_checkuser('a','bb') from dual; -- 回傳 0
-- 直接比對雜湊
select * from test_user t where t.password = test_md5.fn_getmd5('aa');
DBMS_CRYPTO 的 SHA-256/512 或 PBKDF2/BCrypt/Argon2(需外部程式實作)