【Java】Argon2实现密码加密以及在springboot中使用教程

前言

  密码加密是每个计算机软件系统都绕不开的话题,加密也有很多种方式,选择加密方式需要从安全性、可靠性、性能等多方面综合考虑,在众多加密方式中Argon2是一个非常优秀的方案,下面是主流的一些加密方式对比

特性 Argon2id bcrypt scrypt PBKDF2
核心机制 同时消耗 CPU + 内存,且内存访问顺序混合 基于Blowfish加密,仅消耗 CPU 消耗 大量内存(需构造伪随机序列) 仅消耗 CPU(反复执行HMAC)
抗GPU/ASIC 极强(内存成本极高,难以并行) 中等(内存占用仅4KB,易被FPGA/GPU加速) 强(内存占用大,受限于内存带宽) 极弱(内存占用极低,GPU可暴力破解)
可调参数 3个(时间t、内存m、并行度p) 1个(工作因子cost) 2个(CPU成本N、内存成本r) 1个(迭代次数)
默认内存占用 19 MiB(建议值) 4 KB(固定极小) 16 MB+(可调大) 极低(可忽略)
侧信道攻击 Argon2id 混合模式可抵抗 部分抵抗 抵抗 抵抗
优点 安全性最高,抗GPU/ASIC攻击能力最强 成熟稳定,广泛使用,内置盐值 安全性高,有效抵抗硬件暴力破解 合规性好

Argon2是什么?

  Argon2 是当前最先进、最推荐的密码哈希算法。它是2015年"密码哈希竞赛"的冠军,设计上就是为了对抗现代GPU和ASIC破解硬件。它允许你独立配置时间成本、内存成本和并行度三个参数,灵活性极高,并于2021年正式成为IETF标准(RFC 9106)

Argon2有三种变体,各自有不同的应用场景:

变体 说明
Argon2d 使用数据依赖的内存访问方式。它的速度最快,对GPU和ASIC破解的抵抗性最强,但由于内存访问模式与数据相关,容易受到侧信道攻击。因此,它适用于没有侧信道攻击威胁的场景,比如加密货币。
Argon2i 使用数据独立的内存访问方式。它专门为抵抗侧信道攻击而设计,更适合密码哈希和基于密码的密钥派生。但它的安全性略低于Argon2d。
Argon2id 混合模式,也是官方推荐和默认的变体。它结合了前两者的优点:前半部分使用Argon2i(抵抗侧信道),后半部分使用Argon2d(抵抗GPU破解)。对于绝大多数场景,尤其是密码存储,你应该选择 Argon2id。

Argon2id在springboot中使用

引入argon2依赖

xml 复制代码
 <dependency>
    <groupId>de.mkammerer</groupId>
     <artifactId>argon2-jvm</artifactId>
     <version>2.11</version>
 </dependency>

实现工具类,该工具类可以直接复制使用,简单易懂,根据项目实际情况配置一下参数即可以实现加密和验证操作。

java 复制代码
import de.mkammerer.argon2.Argon2;
import de.mkammerer.argon2.Argon2Factory;
/**
 * Argon2 是当前推荐的密码哈希算法(密码哈希竞赛冠军),Argon2id 兼顾抗 GPU 与侧信道攻击,适合存储用户密码
 */
public class Argon2IdUtil {

    // 构建 Argon2id(自动加盐)
    private static final Argon2 ARGON2 = Argon2Factory.create(Argon2Factory.Argon2Types.ARGON2id);

    // 哈希参数, 低配置:3, 65536, 4,高安全:4, 131072, 8(消耗内存更多)服务端可按需调整,内存越大越安全
    //迭代次数
    private static final int ITERATIONS = 3;
    //内存(KB)
    private static final int MEMORY = 65536;
    //并行度
    private static final int PARALLELISM = 4;


    /**
     * 生成密码哈希
     * @param rawPassword 原始明文密码
     * @return 哈希字符串(内置salt,直接入库)
     */
    public static String hash(String rawPassword) {
        char[] chars = rawPassword.toCharArray();
        try {
            return ARGON2.hash(ITERATIONS, MEMORY, PARALLELISM, chars);
        } finally {
            // 清空内存明文,防止密码残留
            ARGON2.wipeArray(chars);
        }
    }

    /**
     * 校验密码
     * @param hash 数据库存储的hash
     * @param rawPassword 前端传入明文
     * @return 是否匹配
     */
    public static boolean verify(String hash, String rawPassword) {
        char[] chars = rawPassword.toCharArray();
        try {
            return ARGON2.verify(hash, chars);
        } finally {
            ARGON2.wipeArray(chars);
        }
    }

    public static void main(String[] args) {
    	String hash = Argon2IdUtil.hash("123456");
    	System.out.println("加密后的密文:"+hash);
    	System.out.println("校验密码:"+Argon2IdUtil.verify(hash, "123456"));
    }
}

运行上面工具类,结果如下:

为了帮助更多像你一样的读者,我将持续在专栏中分享技术干货和实用技巧。如果你觉得这篇文章对你有帮助,可以考虑关注我的专栏,谢谢。

相关推荐
高级程序源几秒前
springboot大学生体测系统72170-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·django·课程设计
谢亮_vipxieliang5 分钟前
JavaScript this 指向完全指南:调用位置决定一切
开发语言·javascript·ecmascript
IT研究室8 分钟前
最新计算机毕业设计选题推荐-基于spring boot的文学名著分享系统-网站-文档指导-Java-springboot
java·spring boot·课程设计
denlaku11 分钟前
JDK 13 新特性详解
java·开发语言
秋饼11 分钟前
Java 后端企业级 LLM 网关实战:Spring Cloud Gateway 构建统一大模型接入层
java·ai·技术分享·后端开发
今年下半年20 分钟前
【防重放】Spring Boot 通过自定义注解实现接口防重放
java·spring boot·自定义注解·防重放
念越23 分钟前
题库、练习与错题本代码阅读
开发语言·数据结构
WeiXin_DZbishe23 分钟前
基于Node.js的马拉松赛事管理系统的设计与实现-计算机毕设 附源码【课程设计】90211
java·javascript·vue.js·python·php·课程设计
l1t25 分钟前
几种数据库软件count(distinct)和count()from group by子查询性能测试
开发语言·数据库
熊猫钓鱼>_>34 分钟前
大学图论第 6 讲:网络流与二分图匹配——对偶性让瓶颈自己现形
开发语言·算法·面试·职场和发展·图论·校招·面经