为什么Digester为相同的消息,代码和迭代生成不同的哈希码

时间:2012-01-05 07:50:57

标签: java encryption hash

我在spring security中编写了一个哈希码隐藏方法。在该方法中,我将在数据库中保存salt值和迭代大小。当用户下次使用普通密码登录时,我将使用salt值并从数据库迭代并消化密码。但是,即使salt和iteration值相同,此方法也会生成不同的哈希码。

public Administrator encryptDigestCode(Administrator administrator) {
    StandardStringDigester digester = new StandardStringDigester();
    Administrator admin = new Administrator();
    digester.setAlgorithm("SHA-256");
    digester.setStringOutputType("base64");
    Random ran = new Random();
    int iterate = ran.nextInt(1000);
    digester.setIterations(iterate);
    RandomSaltGenerator ram = new RandomSaltGenerator();
    byte[] salt = ram.generateSalt(10);
    String pass = new String(salt) + administrator.getHashedPassword();
    String encryptedPassword = digester.digest(pass);
    if (digester.matches(administrator.getHashedPassword(),
            encryptedPassword)) {
        admin.setLoginDetail(new LoginDetail());
        admin.getLoginDetail().setSalt(new String(ram.generateSalt(10)));
        admin.getLoginDetail().setHashingCycle(iterate);
        admin.setUserName(administrator.getUsername());
        admin.setSesamiagreementno(administrator.getSesamiagreementno());
        admin.setHashedPassword(encryptedPassword);
    } else {
        admin.setLoginDetail(null);
        admin.setHashedPassword(null);
        admin.setUserName(null);
    }
    return admin;
}

我该怎么办?任何代码或网站供参考。感谢

2 个答案:

答案 0 :(得分:0)

看起来你使用随机盐。 - 当然哈希总是不同的。


还有第二个随机值

Random ran = new Random();
int iterate = ran.nextInt(1000);
digester.setIterations(iterate);

我希望这也会影响结果。所以,如果你没有运气,那么两次得到相同的随机值,哈希是不同的。

答案 1 :(得分:0)

该行

admin.getLoginDetail().setSalt(new String(ram.generateSalt(10)));

错了。首先,它生成一个新的随机盐并将其放入数据库中 而不是使用变量盐。即你调用generateSalt两次:第一个结果用于散列密码,第二个结果存储在数据库中。其次,它将随机字节数组转换为字符串。 除非您确定这些字节对应于可打印字符,否则您应该例如在这里使用base64编码(当然还有必要的适当解码)。

对迭代次数使用随机整数也不是一个好主意。迭代次数应该使针对单个目标的暴力攻击成本高昂。如果您在此处使用随机数,则攻击者可能只是尝试找到迭代次数最少的用户并开始攻击此密码。