首页 > 解决方案 > 如何将盐与生成的密码进行比较?

问题描述

所以我试图将我的原始密码与加盐的密码进行比较。我知道如何比较哈希密码,我将原始密码添加到它并且它可以工作。但是,我不知道如何比较盐。

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

我该怎么做才能将原始密码与此进行比较?

这就是我的任务所说的,“将生成的密码与存储的盐和散列密码进行比较”。

标签: javasecurityservletscryptographysalt

解决方案


你还应该储存盐。当两个用户选择相同的密码时,Salt 用于防止生成相同的散列密码。类似以下代码可用于将密码保存为 hashedPassord 并验​​证输入的密码。它不完整,但可以用作示例代码。

private static void savePassword(String rawPassword) throws InvalidKeySpecException, NoSuchAlgorithmException {
    byte[] salt = getSalt();
    String hashedPassword = getHashedPassword(rawPassword, salt);
    String encodedSalt = base64Encode(salt);

    /* todo: store hashPassword and encodedSalt */
}

private static boolean verifyPassword(String rawPassword, String hashedPassword, String encodedSalt) throws InvalidKeySpecException, NoSuchAlgorithmException {
    return Objects.equals(hashedPassword, getHashedPassword(rawPassword, base64Decode(encodedSalt)));
}

private static String getHashedPassword(String rawPassword, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
    KeySpec spec = new PBEKeySpec(rawPassword.toCharArray(), salt, 65536, 128);
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    byte[] hash = factory.generateSecret(spec).getEncoded();
    return base64Encode(hash);
}

private static byte[] getSalt() {
    Random r = new SecureRandom();
    byte[] saltBytes = new byte[32];
    r.nextBytes(saltBytes);
    return saltBytes;
}

private static String base64Encode(byte[] src) {
    return Base64.getEncoder().encodeToString(src);
}

private static byte[] base64Decode(String src) {
    return Base64.getDecoder().decode(src);
}

推荐阅读