在Oracle 11g中选择DBMS_CRYPTO密码哈希值

时间:2012-09-17 19:01:06

标签: java oracle11g password-hash dbms-crypto

我目前正在使用DBMS_CRYPTO.HASH在我的Oracle数据库中隐藏我的密码字段。但是,在这一点上,我需要允许我的Java应用程序能够以类似于MySQL的方式验证用户输入的密码。类似的东西:

SELECT *
FROM user_login_table
WHERE password = SHA1('MyPassword');

我目前正在通过以下程序进行哈希处理:

CREATE OR REPLACE PROCEDURE 
  MUNGAI.p_auth_insert_user (
    par_username in varchar2,
    par_password in varchar2,
    par_work in varchar2
  )
IS l_hash raw(2000);
  BEGIN
    l_hash :=
      dbms_crypto.hash(
        utl_i18n.string_to_raw(par_password || par_work || upper(par_username),
        'AL32UTF8'
      ),
      dbms_crypto.hash_sh1
    );

    INSERT INTO user_login_table (user_name, p_word, work_class)
    VALUES (par_username, l_hash, par_work);
  END p_auth_insert_user;
/

然后我按如下方式执行程序,插入表中:

EXEC MUNGAI.p_auth_insert_user('MUNGAI', 'gatungo', '999')

在我的情况下,有没有更好的方法来实现这一目标?如果重要的话,我正在使用Oracle 11g。

2 个答案:

答案 0 :(得分:4)

我建议你在代码外的数据库中进行散列。这样您就可以独立于数据库供应商,并且您必须将散列实现仅写入一个位置。 DB列可以是常规varchar。

这将是这样的:

  1. 添加用户/更改密码时,哈希在插入/更新之前提供了具有适当算法和salt的密码。我建议至少使用SHA-256。保存哈希旁边的盐!

  2. 在身份验证期间,为用户获取哈希和salt,使用salt哈希提供的密码并与数据库中的哈希进行比较。

  3. 散列/腌制的提示,例如:http://crackstation.net/hashing-security.htm

答案 1 :(得分:3)

假设散列密码存储在RAW的{​​{1}}列中,您只需在SQL语句中调用user_login_table即可。根据您执行初始哈希的方式(特别是如何将纯文本密码转换为dbms_crypto.hash以及您正在使用的算法和选项),这样的工作将起作用

RAW

当然,作为良好编码实践的一般问题,您几乎肯定想要定义自己的哈希密码函数,以便您可以嵌入如何将字符串转换为select * from user_login_table where password = dbms_crypto.hash( utl_i18n.string_to_raw( 'MYPassword', 'AL32UTF8' ), <<whatever hash algorithm you want to use>> ); 的逻辑并指定哈希算法在一个地方。然后,您将从SQL语句中调用该新函数。这个功能在某种程度上,您可能会添加适当的盐。然后,您将使用该函数来执行表中散列数据的初始种子设定,并在将来验证密码哈希值。

除了密码之外,我还假设您的实际查询在RAW上有谓词

username

否则,您发布的查询只会验证密码是否与数据库中某人的密码相匹配,而不是尝试登录的特定人员的密码。另外,如果两个人拥有相同的密码哈希,它将返回多行。

因此,在您的具体情况下,我希望您能够创建一个新函数select * from user_login_table where password = new_function_name( 'MYPassword' ) and username = 'YourUserName'

hash_password

然后,您将从插入过程中调用此函数

CREATE OR REPLACE function MUNGAI.hash_password(par_username in varchar2,
                              par_password in varchar2,
                              par_work in varchar2
                             )
  return raw
is
  l_hash raw(2000);
begin
  l_hash :=
   dbms_crypto.hash
     (utl_i18n.string_to_raw (par_password || par_work || upper(par_username),
                              'AL32UTF8'
                             ),
      dbms_crypto.hash_sh1
     );
  return l_hash;
end;

您的查询将是

CREATE OR REPLACE procedure MUNGAI.p_auth_insert_user (par_username in varchar2,
                              par_password in varchar2,
                              par_work in varchar2
                             )
is
  l_hash raw(2000);
begin
  l_hash := hash_password( par_username, par_password, par_work );

  insert into user_login_table
    (user_name, p_word, work_class)
   values
    (par_username, l_hash, par_work);
end p_auth_insert_user;
/