密码存储与传输的那些事儿(四)Scrypt&Argon2密码哈希

Scrpyt    

  如前所述,Scrypt密码哈希的安全性要高于Bcrypt,Scrypt内部还使用了PBKDF2算法,具体算法就不深入研究了,其实从Scrypt的入参就可以看出其安全性,具体入参列表如下:

  • Passphrase:待哈希密码
  • Salt:盐,推荐不小于16字节
  • N:CPU/内存消耗指数,一般取值为2的若干次方,例如16384
  • p:并行计算参数,理论上取值范围为1-255,参数值越大越依赖于并发计算
  • r:表块大小,理论取值范围为1-255,同样越大越依赖内存与带宽
  • dkLen: 表最终生成的结果长度。

      以JAVA代码为例,使用如下Scrypt库


      com.lambdaworks
      scrypt
      1.4.0

      示例代码如下:

String pwd = "123456";
byte[] salt = new byte[16];
SecureRandom.getInstance("SHA1PRNG").nextBytes(salt);
long time = new Date().getTime();
System.out.println(toHexString(SCrypt.scrypt(pwd.getBytes("UTF-8"), salt, 16384, 8, 1, 32)));
System.out.println(String.valueOf(new Date().getTime() - time));

       其中SCrypt.scrpyt方法的参数与上所描述的顺序一致,N、p、r参数均能影响实际计算耗时,为此后续需要根据各自的实际需求来调整参数,同时尽量保证计算时间不高于300ms。


Argon2

       Argon2的入参和Scrypt差不多,但是个人感觉更加量化一些,主要包括如下:

  • password:密码
  • salt:盐
  • parallelism:并发线程数量
  • memorySizeKB:占用内存大小(单位KB)
  • iterations:迭代次数

       看来基本与Scrypt一致,不过参数更加量化一些,不像Scrypt感觉那么抽象。使用起来也较为简单,现成的库如下:


     de.mkammerer
     argon2-jvm
     2.4

       示例代码如下:

Argon2 argon2 = Argon2Factory.create();
String pwd = "123456";
long time = new Date().getTime();
String hash = argon2.hash(2, 65536, 1, pwd, StandardCharsets.UTF_8);
System.out.println(hash);
System.out.println(String.valueOf(new Date().getTime() - time));

       和Scrypt一致,影响计算时间的参数有多个,具体参数的选择还是需要根据实际的需求去调整,遗憾的是Argon2暂未找到相应的Javascript实现。

你可能感兴趣的:(安全)