增加Argon2类,实现Argon2算法(issue#3890@Github)

This commit is contained in:
Looly 2025-04-11 10:45:04 +08:00
parent 5c66079f15
commit a618001723
3 changed files with 175 additions and 0 deletions

View File

@ -7,6 +7,7 @@
### 🐣新特性 ### 🐣新特性
* 【core 】 `PathUtil#del`增加null检查pr#1331@Gitee * 【core 】 `PathUtil#del`增加null检查pr#1331@Gitee
* 【db 】 增加SAP HANA识别及方言pr#3914@Github * 【db 】 增加SAP HANA识别及方言pr#3914@Github
* 【crypto 】 增加`Argon2`实现Argon2算法issue#3890@Github
### 🐞Bug修复 ### 🐞Bug修复

View File

@ -0,0 +1,152 @@
package cn.hutool.crypto.digest;
import org.bouncycastle.crypto.generators.Argon2BytesGenerator;
import org.bouncycastle.crypto.params.Argon2Parameters;
/**
* Argon2加密实现
*
* @author changhr2013
* @author Looly
* @since 5.8.38
*/
public class Argon2 {
/**
* 默认hash长度
*/
public static final int DEFAULT_HASH_LENGTH = 32;
private int hashLength = DEFAULT_HASH_LENGTH;
private final Argon2Parameters.Builder paramsBuilder;
/**
* 构造默认使用{@link Argon2Parameters#ARGON2_id}类型
*/
public Argon2(){
this(Argon2Parameters.ARGON2_id);
}
/**
* 构造
*
* @param type {@link Argon2Parameters#ARGON2_d}{@link Argon2Parameters#ARGON2_i}{@link Argon2Parameters#ARGON2_id}
*/
public Argon2(int type){
this(new Argon2Parameters.Builder(type));
}
/**
* 构造
*
* @param paramsBuilder 参数构造器
*/
public Argon2(Argon2Parameters.Builder paramsBuilder){
this.paramsBuilder = paramsBuilder;
}
/**
* 设置hash长度
*
* @param hashLength hash长度
* @return this
*/
public Argon2 setHashLength(int hashLength){
this.hashLength = hashLength;
return this;
}
/**
* 设置版本
*
* @param version 版本
* @return this
* @see Argon2Parameters#ARGON2_VERSION_10
* @see Argon2Parameters#ARGON2_VERSION_13
*/
public Argon2 setVersion(int version){
this.paramsBuilder.withVersion(version);
return this;
}
/**
* 设置盐
*
* @param salt
* @return this
*/
public Argon2 setSalt(byte[] salt){
this.paramsBuilder.withSalt(salt);
return this;
}
/**
* 设置可选的密钥数据用于增加哈希的复杂性
*
* @param secret 密钥
* @return this
*/
public Argon2 setSecret(byte[] secret){
this.paramsBuilder.withSecret(secret);
return this;
}
/**
* @param additional 附加数据
* @return this
*/
public Argon2 setAdditional(byte[] additional){
this.paramsBuilder.withAdditional(additional);
return this;
}
/**
* 设置迭代次数<br>
* 迭代次数越多生成哈希的时间就越长破解哈希就越困难
*
* @param iterations 迭代次数
* @return this
*/
public Argon2 setIterations(int iterations){
this.paramsBuilder.withIterations(iterations);
return this;
}
/**
* 设置内存单位KB<br>
* 内存越大生成哈希的时间就越长破解哈希就越困难
*
* @param memoryAsKB 内存单位KB
* @return this
*/
public Argon2 setMemoryAsKB(int memoryAsKB){
this.paramsBuilder.withMemoryAsKB(memoryAsKB);
return this;
}
/**
* 设置并行度即同时使用的核心数<br>
* 值越高生成哈希的时间就越长破解哈希就越困难
*
* @param parallelism 并行度
* @return this
*/
public Argon2 setParallelism(int parallelism){
this.paramsBuilder.withParallelism(parallelism);
return this;
}
/**
* 生成hash值
*
* @param password 密码
* @return hash值
*/
public byte[] digest(char[] password){
final Argon2BytesGenerator generator = new Argon2BytesGenerator();
generator.init(paramsBuilder.build());
byte[] result = new byte[hashLength];
generator.generateBytes(password, result);
return result;
}
}

View File

@ -0,0 +1,22 @@
package cn.hutool.crypto.digest;
import cn.hutool.core.codec.Base64;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class Argon2Test {
@Test
public void argon2Test() {
Argon2 argon2 = new Argon2();
final byte[] digest = argon2.digest("123456".toCharArray());
Assertions.assertEquals("wVGMOdzf5EdKGANPeHjaUnaFEJA0BnAq6HcF2psFmFo=", Base64.encode(digest));
}
@Test
public void argon2WithSaltTest() {
final Argon2 argon2 = new Argon2();
argon2.setSalt("123456".getBytes());
final byte[] digest = argon2.digest("123456".toCharArray());
Assertions.assertEquals("sEpbXTdMWra36JXPVxrZMm3xyoR5GkMlLhtW0Kwp9Ag=", Base64.encode(digest));
}
}