我的Salting和SHA-512哈希密码的实现是否正确/安全?

Aur*_*rum 2 java security cryptography salt sha512

我的Salting和SHA-512哈希密码的实现是否正确/安全?

我知道我应该在盐渍密码上迭代算法几次.除此之外,我应该实施什么才能使其安全或者这足够了?

        public static String[] SHA512(String password)
{
    //Generates the salt
    SecureRandom saltRandomizer = new SecureRandom();
    byte[] salt = new byte[64]; //The same size as the output of SHA-512 (512 bits = 64 bytes)
    saltRandomizer.nextBytes(salt);
    String encodedSalt = Base64.encodeToString(salt, Base64.DEFAULT);


    //Prepends the salt to the password
    String saltedPassword = encodedSalt + password;

    //Hashed the salted password using SHA-512
    MessageDigest digester;
    byte[] digest = null;
    try {
        digester = MessageDigest.getInstance("SHA-512");
        digester.reset();
        digester.update(saltedPassword.getBytes());
        digest = digester.digest();
    } catch (NoSuchAlgorithmException e) {
        System.out.println("No such algorithm");
        e.printStackTrace();
    }

    String[] passwordPlusSalt = new String[2];
    passwordPlusSalt[0] = Base64.encodeToString(digest, Base64.DEFAULT);
    passwordPlusSalt[1] = encodedSalt;
    return passwordPlusSalt;
}
Run Code Online (Sandbox Code Playgroud)

提前致谢

hoi*_*loi 6

不,它不安全.看看这一行:

SecureRandom saltRandomizer = new SecureRandom();
Run Code Online (Sandbox Code Playgroud)

我注意到您没有指定PRNG或提供商.我不是专家,但我理解SUN CSP默认是在Solaris和Linux上使用sun.security.provider.NativePRNG,它只提供/ dev/urandom的输出,它可能(或可能不)适合您的需要(例如,它不建议用于生成加密密钥).

因此,建议始终指定PRNG和提供者,如下所示:

SecureRandom.getInstance("SHA1PRNG", "SUN");
Run Code Online (Sandbox Code Playgroud)

此外,建议:

  • 定期丢弃现有的java.security.SecureRandom实例并创建一个新实例.这将生成一个带有新种子的新实例.
  • 通过调用java.security.SecureRandom.setSeed(java.security.SecureRandom.generateSeed(int)),定期向PRNG种子添加新的随机材料.

我要说的是,安全性是一个很容易出错的复杂话题.不要试图自制一个解决方案.使用现有库.引用Thomas Pornin的优秀答案:

复杂性很糟糕.自制很糟糕.新的很糟糕.

资料来源:

  • `/ dev/urandom`通常适用于生成加密密钥.重播也不重要,但由于OP为每个调用生成一个新实例,因此它肯定会经常重新播种. (2认同)