【问题标题】:Hashing and salting a password, then trying to get the unhashed password later对密码进行散列和加盐处理,然后稍后尝试获取未散列的密码
【发布时间】:2017-09-30 16:13:51
【问题描述】:

我创建了一个用于散列和加盐密码的实用程序类。然后我将用户的密码存储在用户表中的 SQL 数据库中。我想使用 EL 从数据库中提取密码,解密并在 JSP 中显示。如何解密从数据库中取回的密码?这是实用程序类:

公共类 PasswordUtil {

/*  This code uses SHA-256. If this algorithm isn't available to you,
    you can try a weaker level of encryption such as SHA-128.
*/    
public static String hashPassword(String password)
        throws NoSuchAlgorithmException {        
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.reset();
    md.update(password.getBytes());
    byte[] mdArray = md.digest();
    StringBuilder sb = new StringBuilder(mdArray.length * 2);
    for (byte b : mdArray) {
        int v = b & 0xff;
        if (v < 16) {
            sb.append('0');
        }
        sb.append(Integer.toHexString(v));
    }        
    return sb.toString();        
}

public static String getSalt() {
    Random r = new SecureRandom();
    byte[] saltBytes = new byte[32];
    r.nextBytes(saltBytes);
    return Base64.getEncoder().encodeToString(saltBytes);
}

public static String hashAndSaltPassword(String password)
        throws NoSuchAlgorithmException {
    String salt = getSalt();
    return hashPassword(password + salt);
}

public static void checkPasswordStrength(String password) throws Exception {
    if (password == null || password.trim().isEmpty()) {
        throw new Exception("Password cannot be empty.");
    } else if (password.length() < 8) {
        throw new Exception("Password is to short. " +
                "Must be at least 8 characters long.");
    }
}

public static boolean validatePassword(String password) {
    try {
        checkPasswordStrength(password);
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return false;
    }
    return true;
}

}

这是我想在其上显示解密密码的 JSP(为简洁起见,只是来自 JSP 的表格):

     <table> 
            <tr>
                <td class="alignRight">First Name:</td>
                <td>${user.firstName}</td>
            </tr>
            <tr>
                <td class="alignRight">Last Name:</td>
                <td>${user.lastName}</td>
            </tr>
            <tr>
                <td class="alignRight">Phone Number:</td>
                <td>${user.phone}</td>
            </tr>
            <tr>
                <td class="alignRight">Address:</td>
                <td>${user.address}</td>
            </tr>
            <tr>
                <td class="alignRight">City:</td>
                <td>${user.city}</td>
            </tr>
            <tr>
                <td class="alignRight">State:</td>
                <td>${user.state}</td>
            </tr>
            <tr>
                <td class="alignRight">Zipcode:</td>
                <td>${user.zip}</td>
            </tr>
            <tr>
                <td class="alignRight">Email:</td>
                <td>${user.email}</td>
            </tr>
            <tr>
                <td class="alignRight">Your user name is:</td>
                <td>${user.userName}</td>
            </tr>
            <tr>
                <td class="alignRight">Temporary password:</td>
                <td>${user.password}</td>
            </tr>
        </table>

【问题讨论】:

  • 我想使用 EL 从数据库中提取密码,解密并显示在 JSP 中。 这看起来像 真的糟糕 想法。
  • 老实说,解密密码要好得多(更安全),而是将一种加密与数据库中保存的另一种加密进行比较以进行匹配。
  • 您不必解散密码即可实现该目标。您只需要在哈希之前显示原始密码。
  • 不要加密密码,当攻击者得到数据库时,他也会得到加密密钥。仅使用散列函数是不够的,仅添加盐对提高安全性无济于事。使用随机盐在 HMAC 上迭代大约 100 毫秒,然后将盐与哈希一起保存。使用password_hashPBKDF2Bcrypt 等函数或类似函数。关键是让攻击者花费大量时间通过蛮力寻找密码。
  • 我没有被要求取消散列,但我想知道如果你需要,你会怎么做散列的整个目的是防止人们完全这样做那。 hashing != encryption.

标签: java jsp encryption hash salt


【解决方案1】:

你不能。

在我看来,您使用的是单向哈希函数 SHA-256。单向散列函数的想法是它只去一种方式;您无法撤消哈希。

如果您希望能够恢复存储在数据库中的“已消化”密码,则必须查看“双向哈希函数”(加密/解密)。正如 Elliott Frisch 所说,这对我来说听起来是个非常糟糕的主意。

【讨论】:

    【解决方案2】:

    无法做到这一点是散列密码的整个点。 (请注意,您不是存储用户的密码;您存储的是哈希值。)

    但是,如果您对此一无所知,您可以尝试使用盐创建自己的彩虹表。

    【讨论】:

    • 当然,仅使用盐进行密码散列是不安全的,不应该这样做。此外,由于盐是随机的,因此不可能创建彩虹表,或者更具体地说,每个盐都需要一个彩虹表,并且每个彩虹表必须有 2^256 个条目,每个条目大约 40 个字节......哇是大。
    猜你喜欢
    • 2019-07-11
    • 2015-02-17
    • 2015-08-20
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 2011-10-29
    相关资源
    最近更新 更多