org.apache.commons.codec.digest.Crypt导致无效盐值异常



下面的代码导致java.lang.IllegalArgumentException随机但不总是,并且在一台计算机上,而不是用于测试的其他计算机上。异常原因为Invalid salt value: $6$+E3Vebci/+lhkquntg==。使用SHA512 ($6$)调用Crypt.crypt()时。我可以看到Crypt有一个模式来检查有效的盐:“^\$([56])\$(rounds=(\d+)\$)?([\.\/a-zA-Z0-9]{1,16}).*“

JDK版本为openjdk 15.0.1 2020-10-20, common -codec版本为1.15

我只是想知道为什么这种情况随机发生在一台Windows 10计算机上,而不是在另一台(M1上的macOS Big Sur)上。然后我应该用不同的方式来制作盐来避免这种例外吗?在网上找不到类似的

byte bytes[] = new byte[13]; 
secureRandom.nextBytes(bytes); // java.security.SecureRandom
String saltBytes = new String(Base64.getEncoder().encode(bytes));
String salt = "$6$" + saltBytes;
String hashedPassword = Crypt.crypt(user.getPassword(), salt);

堆栈跟踪在第181行org.apache.commons.codec.digest.Sha2Crypt.sha2Crypt处结束。

PC为MateBook D Intel Core i7-855OU, Windows 10 Home v 1909 build 18363.1379

来自crypto(String key, String salt)的文档

确切的算法取决于salt字符串的格式:

  • SHA-512盐以$6$开头,最长16个字符。

    salt字符串的其余部分从集合[a-zA-Z0-9]中抽取。/]的最大长度被剪切为"$"遇到符号。

    抛出:
    IllegalArgumentException -如果盐不匹配允许的模式

由于Base64编码的字符串可能包含正则表达式[a-zA-Z0-9./]中不允许的"=", "+",当生成的salt中出现一些无效字符时,您将随机看到错误。

解决方案:

  1. 简单地使用crypto(String key)代替,因为它已经提供了随机盐。
  2. 或者按照允许的模式生成盐。

参考文献:
rfc4648 -表1:Base 64字母表

最新更新