1

我目前在我的 Oracle 数据库中使用DBMS_CRYPTO.HASH. 然而,此时,我需要让我的 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。

4

2 回答 2

4

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

它会是这样的:

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

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

例如这里的散列/加盐技巧:http: //crackstation.net/hashing-security.htm

于 2012-09-17T19:14:20.193 回答
3

假设哈希密码存储在 中的RAW列中user_login_table,您可以简单地调用dbms_crypto.hashSQL 语句。根据您进行初始哈希的方式(特别是您如何将纯文本密码转换为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>> );

当然,作为良好编码实践的一般问题,您几乎肯定希望定义自己的哈希密码函数,以便您可以嵌入如何将字符串转换为 a 的逻辑,RAW并在一个地方指定哈希算法。然后,您将从 SQL 语句中调用该新函数。这就是你可能会添加适当盐的功能。然后,您将使用该函数对表中的散列数据进行初始播种,并在将来验证密码散列。

我还假设您的实际查询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;
/

您的查询将是

select * 
  from user_login_table 
 where password = new_function_name( username, 
                                     'MYPassword', 
                                     <<whatever `par_work` is supposed to be>> )
   and username = 'YourUserName'
于 2012-09-17T20:42:45.657 回答