You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Argon2返回固定长度为17字符的哈希值段?

关于Argon2获取固定17字符哈希值的问题

我使用Java的de.mkammerer.argon2库,通过Argon2算法对字符串编码,因需设置固定盐、固定哈希长度等参数,故使用了Argon2的高级接口。目前无法实现获取长度固定为17字符的哈希值段(对应defaultHashLen参数,该参数单位为字节,编码格式为UTF-8)。请问是否有办法强制Argon2返回长度最大为17的编码值?这是否可行?我尝试截取结果,但修改defaultHashLen的值(如17、22)时,每次执行得到的哈希值段完全不同,不清楚原因。

代码示例

import de.mkammerer.argon2.*;

import java.util.Base64;

public class PasswordArgon2Jvm {

private static final int defaultSaltLen = "abcdefghijklmnopqrst".getBytes().length;
private static final byte[] saltArray = "abcdefghijklmnopqrst".getBytes();
private static final int defaultHashLen = 17;
private static final int iterations = 3;
private static final int memory = 1258;
private static final int parallelism = 3;

public void hashPasswordWithCustomSalt(String pass){

    // public static Argon2Advanced createAdvanced(Argon2Factory.Argon2Types type, int defaultSaltLength, int defaultHashLength) {
    Argon2Advanced argon3 = Argon2Factory.createAdvanced(defaultSaltLen, defaultHashLen);
    byte[] password = pass.toUpperCase().getBytes();
    
    HashResult hashInBytes = argon3.hashAdvanced(iterations, memory, parallelism, password, saltArray, defaultHashLen, Argon2Version.DEFAULT_VERSION);
    String hashWithFixedSalt = hashInBytes.getEncoded();
    String lastBit = hashWithFixedSalt.substring(hashWithFixedSalt.lastIndexOf("$")+1);
    System.out.println(
      pass + " \n" +
      hashWithFixedSalt + " \n" +
      lastBit + " \n" +
      "length: " + lastBit.length() + " \n" +
      "decoded: " + Base64.getDecoder().decode(lastBit));
}

public static void main(String[] args) {
    PasswordArgon2Jvm pa2jvm = new PasswordArgon2Jvm();
    pa2jvm.hashPasswordWithCustomSalt("santiago2");
}

输出结果

santiago2
$argon2i$v=19$m=1258,t=3,p=3$ZFh2dGZIWDRYdGpsV3J0OFh4NEM$2kNm9mxm8XaWcW4KIL+G7Eo
2kNm9mxm8XaWcW4KIL+G7Eo
length: 23
decoded: [B@1a86f2f1

问题解答

  • 字节长度与Base64编码长度的混淆:defaultHashLen指定的是哈希结果的字节长度,而非最终Base64编码后的字符长度。Base64编码规则是每3字节对应4字符,不足部分补位,因此17字节的哈希结果编码后会是23字符(ceil(17*4/3)=23),这是编码机制决定的,Argon2本身无法直接返回17字符的编码值。

  • 修改defaultHashLen导致哈希值变化的原因:不同的defaultHashLen会让Argon2生成不同长度的哈希字节流,算法输出的哈希值本身就会不同,这是正常现象——你要求算法生成不同长度的结果,自然会得到不同的哈希值段。

  • 获取最长17字符编码值的可行方案:

    1. 截取编码结果:先获取指定字节长度的哈希,再对Base64编码后的字符串截取前17字符。但注意:这种操作会损失哈希的熵,增加碰撞风险,不推荐用于密码存储等安全场景。
    2. 调整哈希字节长度适配Base64:Base64编码后字符长度与字节长度的对应关系是:每3字节对应4字符。若要编码后字符长度≤17,哈希字节长度最大设为12(12字节编码后为16字符);若接受18字符则设为13字节,但无法刚好得到17字符的编码结果(Base64编码长度是4的倍数或补位后的长度,无17字符的情况)。
  • 补充:字节数组打印问题:你输出中的[B@1a86f2f1是直接打印字节数组对象的内存地址,若要查看字节内容,可改用Arrays.toString(Base64.getDecoder().decode(lastBit))。


内容的提问来源于stack exchange,提问作者Aisatora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:06:18