当前位置: 首页 > news >正文

【Spring Boot】Spring Boot 中常见的加密方案

Spring Boot 中常见的加密方案

  • MD5
    • MD5 基本概念
    • MD5 的核心思想
    • MD5 使用方法
  • SHA 系列
    • SHA 系列概述
    • SHA 的工作原理(通用流程)
    • SHA 使用方法
  • BCrypt
    • BCrypt 概念
    • BCrypt 的工作原理(内部流程)
    • BCrypt 使用方法
  • Argon2
    • Argon2 概念
    • Argon2 设计思想
    • Argon2 使用方法
  • Spring Boot 项目使用
  • 总结

MD5

MD5 基本概念

MD5 全称是 Message Digest Algorithm 5(信息摘要算法第 5 版),由密码学家 Ron Rivest 在 1991 年提出。

它的作用是:
把任意长度的数据(字符串、文件等)“压缩”成一个固定长度的 128 位(16 字节)摘要值

这个摘要值通常用 32 位十六进制字符串表示。

示例

输入: "hello"
输出: 5d41402abc4b2a76b9719d911017c592

即使只改变一个字符:

输入: "Hello"
输出: 8b1a9953c4611296a827abf8c47804d7

可以看到:输入微小变化,输出完全不同

MD5 的核心思想

MD5 并不是“加密”,而是一种哈希算法(Hash Function)

即:

  • 不可逆(你无法从 MD5 值反推出原文)
  • 定长输出(无论输入多长,输出始终是 128 位)
  • 雪崩效应(输入改动一位,输出几乎全变)
  • 高速计算(适合快速校验)

原理简述

MD5 的内部逻辑大致如下:

步骤描述
填充(Padding)将输入填充到长度 ≡ 448 mod 512,确保数据能被分为 512 位的块。
附加长度在数据末尾追加原始长度(64 位)。
初始化缓冲区定义 4 个 32 位寄存器:A、B、C、D(初始常量)。
迭代运算每个 512 位块通过一系列非线性函数和位运算(如 AND、OR、XOR、左移)混合处理。
输出结果最终拼接 A、B、C、D 的值 → 128 位摘要。

简单来说:MD5 把输入“分块 → 混合 → 扰乱 → 压缩”成固定长度摘要。

MD5 的特点

特性说明
输出长度固定128 位(16 字节),常以 32 个十六进制字符表示。
不可逆无法解密回原始内容。
雪崩效应输入变化 1 bit,输出变化约 50%。
快速计算算法效率高。
碰撞风险不同的输入可能生成相同的输出(已被证明)。

MD5 的常见用途

应用场景说明
文件完整性校验下载软件时验证文件未被篡改。
数据校验码快速比较数据内容是否一致。
用户密码加密(旧系统)曾经常用于存储密码(但已不安全)。
数字签名在安全性较低场景中生成签名摘要。

MD5 使用方法

使用 Spring 自带工具类

Spring 框架提供了简单的 MD5 工具:

import org.springframework.util.DigestUtils;public class MD5Example {public static void main(String[] args) {String input = "hello";String md5 = DigestUtils.md5DigestAsHex(input.getBytes());System.out.println(md5);}
}

输出:

5d41402abc4b2a76b9719d911017c592

使用 Java 原生 API

import java.security.MessageDigest;public class MD5Example {public static void main(String[] args) throws Exception {String input = "hello";MessageDigest md = MessageDigest.getInstance("MD5");byte[] hashBytes = md.digest(input.getBytes("UTF-8"));StringBuilder hex = new StringBuilder();for (byte b : hashBytes) {hex.append(String.format("%02x", b));}System.out.println(hex.toString());}
}

给密码加盐(增强安全)

加盐(Salt)可以防止彩虹表攻击。

import java.security.MessageDigest;public class SaltedMD5 {public static void main(String[] args) throws Exception {String password = "123456";String salt = "MyApp#2025";String input = password + salt;MessageDigest md = MessageDigest.getInstance("MD5");byte[] bytes = md.digest(input.getBytes("UTF-8"));StringBuilder hex = new StringBuilder();for (byte b : bytes) hex.append(String.format("%02x", b));System.out.println(hex.toString());}
}

MD5 的安全性问题

MD5 已不安全,不推荐用于密码或安全签名。

原因如下:

问题描述
碰撞攻击不同输入可得相同 MD5 值。2004 年被正式破解。
彩虹表攻击攻击者用预计算表快速反查 MD5 值。
暴力破解由于算法速度太快,适合 GPU 暴力破解。

SHA 系列

SHA 系列概述

SHA(Secure Hash Algorithm) 是由美国 NSA(国家安全局) 设计、NIST(国家标准与技术研究院) 发布的加密哈希家族。

它的作用与 MD5 类似:将任意长度的数据映射为固定长度的“摘要”(digest),用于校验完整性、签名、认证等。

SHA 家族主要分为以下几代:

系列代表算法输出长度(bit)状态说明
SHA-0SHA-0160已废弃原版算法(1993),发现安全漏洞,被迅速弃用
SHA-1SHA-1160已被破解曾广泛用于 SSL、Git、证书签名等,现在不安全
SHA-2SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256224~512主流标准当前主流使用的安全哈希算法族(JWT、TLS、密码哈希)
SHA-3SHA3-224、SHA3-256、SHA3-384、SHA3-512224~512新一代标准与 SHA-2 完全不同,基于 Keccak 算法,更抗攻击

SHA 的工作原理(通用流程)

SHA 的计算过程与 MD5 类似,但逻辑更复杂、更安全:

阶段说明
预处理填充数据到 512 位的整数倍,附加长度信息
分块每个 512 位分块单独处理
初始化变量设定若干 32 位或 64 位寄存器(A、B、C、D…)
循环压缩通过逻辑函数、位移、模加等运算混合数据
拼接结果输出固定长度摘要(如 256 位 = 32 字节)

SHA 的核心是“不可逆的数学混合”。
输入稍有改动,输出完全不同(雪崩效应)。

SHA 使用方法

SHA-1(Secure Hash Algorithm 1)

  • 输出长度:160 位(20 字节)
  • 常见输出格式:40 位十六进制字符串
  • 算法速度:快
  • 安全性:已被破解
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] result = md.digest("hello".getBytes());

曾用于:

  • SSL/TLS 证书签名(已弃用)
  • Git 文件版本校验(正在过渡到 SHA-256)

已被 Google 和荷兰CWI研究所于 2017 年展示 实际碰撞攻击(SHAttered)

SHA-2 系列(主流标准)

SHA-2 实际是多个算法族的统称:

算法输出长度常见用途
SHA-224224 位嵌入式、低功耗设备
SHA-256256 位最常用(JWT、文件校验)
SHA-384384 位高强度安全
SHA-512512 位适合 64 位系统

SHA-256 是当前最推荐的通用版本。
SHA-512 性能更高(在 64 位机器上),更安全。

Java 实现示例(SHA-256)

import java.security.MessageDigest;public class SHA256Example {public static void main(String[] args) throws Exception {String input = "hello world";MessageDigest digest = MessageDigest.getInstance("SHA-256");byte[] hash = digest.digest(input.getBytes("UTF-8"));StringBuilder hex = new StringBuilder();for (byte b : hash) {hex.append(String.format("%02x", b));}System.out.println(hex.toString());}
}

输出(固定 64 位十六进制串):

b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

Spring Boot 工具类实现(SHA-512)

import org.apache.commons.codec.digest.DigestUtils;String sha512 = DigestUtils.sha512Hex("password123");
System.out.println(sha512);

文件校验场景

import java.io.*;
import java.security.MessageDigest;public static String getFileSHA256(File file) throws Exception {MessageDigest digest = MessageDigest.getInstance("SHA-256");try (InputStream fis = new FileInputStream(file)) {byte[] buffer = new byte[8192];int n;while ((n = fis.read(buffer)) > 0) {digest.update(buffer, 0, n);}}byte[] hash = digest.digest();StringBuilder sb = new StringBuilder();for (byte b : hash) sb.append(String.format("%02x", b));return sb.toString();
}

SHA-3 系列(Keccak)

  • 发布年份:2015(NIST 新标准)
  • 算法基础:基于海绵结构(Sponge Construction)
  • 代表算法:SHA3-224、SHA3-256、SHA3-384、SHA3-512
  • 区别:与 SHA-2 完全不同的内部结构,更抗攻击。
MessageDigest sha3 = MessageDigest.getInstance("SHA3-256");
byte[] hash = sha3.digest("Hello SHA3".getBytes());

特点

  • 不与 SHA-2 兼容;
  • 可抗长度扩展攻击;
  • 设计为长期替代 SHA-2。

补充说明:

概念说明
SHA-2 并不是单一算法它是一整套算法族(不同输出长度的变种)。例如 SHA-256SHA-512 都属于 SHA-2 家族。
SHA-3 并不是 SHA-2 的改进版它是全新设计(Keccak 结构),没有继承关系。
输出长度对应输出摘要长度(bit 位数),例如:SHA-256 输出 256 位(32 字节)。
安全状态SHA-1 已可被构造碰撞,SHA-2 目前仍安全,SHA-3 为未来标准。

正确理解层级关系

SHA(安全哈希算法家族)├── SHA-0(不安全,废弃)├── SHA-1(不安全,已被破解)├── SHA-2(主流安全标准)│     ├── SHA-224│     ├── SHA-256│     ├── SHA-384│     └── SHA-512└── SHA-3(新标准,基于 Keccak)├── SHA3-224├── SHA3-256├── SHA3-384└── SHA3-512

BCrypt

BCrypt 概念

BCrypt 是什么?

BCrypt 是一种基于 Blowfish 加密算法 的密码哈希函数,由 Niels Provos 和 David Mazières 在 1999 年设计,最初出现在 OpenBSD 系统中。
它属于 单向加密算法(Hashing Algorithm),常用于存储用户密码。

BCrypt 的核心特点

特点说明
单向不可逆无法从哈希值反推明文密码。
自动加盐(Salt)每次加密自动生成随机盐,避免彩虹表攻击。
可调“复杂度因子”(Cost Factor)可以调整计算强度,防止暴力破解。
输出固定长度(60字符)无论输入多长,输出总是 60 个字符。
跨语言支持在 Java、Python、PHP、Go 等语言中都有官方或成熟实现。

BCrypt 的工作原理(内部流程)

BCrypt 的计算过程大致如下:

1. 生成随机盐(Salt)↓
2. 将盐与明文密码结合↓
3. 使用 Blowfish 加密算法多轮加密(2^cost 次)↓
4. 输出最终的哈希字符串(包含盐和成本信息)

BCrypt 哈希的格式如下:

$2a$10$EIXCh1l6Z7CzWIKQ0s1t8u8mvjU7qg3sK9fRf6RPSZ6bEJ3iRzZ6G
│ │ │ │                      └───────────────────────────── 密文部分(Base64编码)
│ │ │ └── 22字符的盐(Base64编码)
│ │ └──── 10 表示成本(2^10 = 1024 次加密)
│ └─────── 算法版本(2a/2b)
└───────── 起始符号 $

成本因子(Cost Factor)

BCrypt 的强度主要取决于 cost 参数(也叫 work factor)。
默认一般是 10,表示进行 2^10 = 1024 轮加密。

Cost大约耗时(现代 CPU)
8< 100ms
10~300ms
12~1s
14~4s

建议值:
Web 应用中推荐使用 10~12,兼顾安全与性能。
越高越安全,但登录时耗时也更长。

BCrypt 的安全机制详解

  1. 自动加盐

    每次加密都会自动生成 随机盐(16字节)
    因此即使两个人使用相同密码,哈希值也完全不同。

    $2a$10$abc123...   ← 盐不一样
    $2a$10$xyz987...   ← 哈希也不一样
    
  2. 自带盐与成本参数

    BCrypt 生成的字符串内部就包含盐和 cost,因此不需要单独存储盐。

BCrypt 使用方法

Spring Security 内置了 BCryptPasswordEncoder,使用极其方便。

示例一:生成密码哈希

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;public class BCryptExample {public static void main(String[] args) {BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();String rawPassword = "mySecret123";String hashedPassword = encoder.encode(rawPassword);System.out.println("原始密码: " + rawPassword);System.out.println("加密后: " + hashedPassword);}
}

输出示例:

原始密码: mySecret123
加密后: $2a$10$e0NR9ZnPS2D2X4xDJH5lBO8xL61jSwB1KkzIUVwFovYCKNH4I5C.O

示例二:验证密码是否匹配

String inputPassword = "mySecret123";
boolean matches = encoder.matches(inputPassword, hashedPassword);System.out.println(matches ? "密码正确" : "密码错误");

Argon2

Argon2 概念

什么是 Argon2?

Argon2 是一种用于**密码哈希(Password Hashing)**的算法,诞生于 2015 年,由 Alex Biryukov、Daniel Dinu、Dmitry Khovratovich 等密码学家设计。
它在 2015 年赢得了 Password Hashing Competition (PHC),成为国际标准密码哈希算法。

目标
抵抗暴力破解、GPU 攻击、ASIC 硬件攻击 —— 并提供可调的计算复杂度与内存占用。

Argon2 的三个变种

版本主要特征推荐用途
Argon2d使用数据相关内存访问(速度快)抵御 GPU 攻击(不适合并行攻击)
Argon2i使用数据独立访问(更安全)防止侧信道攻击(如时间推测)
Argon2id混合模式(先 i 后 d)最推荐,兼顾两者优点

在实际项目中:

Argon2id 是目前密码存储的官方推荐版本(RFC 9106 标准)

Argon2 设计思想

传统算法(如 BCrypt)仅考虑“计算耗时”,
Argon2 同时考虑 CPU + 内存消耗,让暴力破解更难:

因素含义攻击难度影响
Time Cost运算迭代次数增加计算量
Memory Cost占用内存(KB/MB)降低 GPU 并行破解效率
Parallelism并行线程数提升合法加密速度

工作原理(简化流程)

  1. 生成随机盐(16字节或更长)
  2. 结合明文密码 + 盐 + 参数(内存/时间/并行度)
  3. 进行多轮基于内存的哈希计算
  4. 输出哈希字符串(包含所有参数)

输出结果示例:

$argon2id$v=19$m=65536,t=3,p=4$QWERTYasdfgh1234$NqM6cN6Lk5mZtP4xGVg4xg
│───────││───── 参数说明 ─────││─── Base64盐 ───││────── 哈希结果 ──────│
│  算法  ││版本│内存=64MB,迭代3次,4线程│ 

Argon2 参数详解

参数含义推荐值(Web 应用)
t (Time Cost)迭代次数2~4
m (Memory Cost)使用内存大小(KB)65536 (≈64MB)
p (Parallelism)并行线程数1~4
salt length盐长度≥16字节
hash length输出哈希长度32字节或更长

安全建议:

  • 盐必须随机且唯一
  • 增加 m(内存)比增加 t(次数)更能防 GPU 攻击
  • 建议使用 Argon2id 模式

为什么 Argon2 比 BCrypt 更安全?

特性BCryptArgon2
加盐机制自动加盐自动加盐
可调复杂度costtime + memory + parallel
GPU 防御强(高内存占用)
并行支持
性能中等
安全标准无官方标准RFC 9106 标准

Argon2 使用方法

Spring Security 从 5.0 版本开始原生支持 Argon2
使用方式与 BCrypt 类似。

添加依赖

在 Spring Boot 项目中引入 Spring Security:

<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-crypto</artifactId>
</dependency>

创建 Argon2PasswordEncoder

import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;public class Argon2Example {public static void main(String[] args) {// 参数:saltLength, hashLength, parallelism, memoryCost, iterationsPasswordEncoder encoder = new Argon2PasswordEncoder(16, 32, 1, 65536, 3);String rawPassword = "mySecret123";String encoded = encoder.encode(rawPassword);System.out.println("原始密码: " + rawPassword);System.out.println("加密后: " + encoded);boolean match = encoder.matches("mySecret123", encoded);System.out.println("匹配结果: " + match);}
}

输出示例:

原始密码: mySecret123
加密后: $argon2id$v=19$m=65536,t=3,p=1$xA4xv2x4lQv4a7g3xA$F6xK3v2n8dQOpxV1u+3Bfw
匹配结果: true

Spring Boot 项目使用

MD5

  • 性质:哈希算法(不可逆),Spring 不提供原生封装,只是工具类(DigestUtils

  • 使用方式:直接调用工具方法即可

    import org.springframework.util.DigestUtils;String md5 = DigestUtils.md5DigestAsHex("password".getBytes());
    
  • 配置类不需要

  • 注意事项

    • MD5 已不安全,不建议用作密码存储
    • 可以用于文件校验、数据完整性等场景

SHA 系列(SHA-1、SHA-256、SHA-512、SHA3 等)

  • 性质:哈希算法(不可逆)

  • 使用方式

    • Java 原生:

      MessageDigest md = MessageDigest.getInstance("SHA-256");
      byte[] hash = md.digest("password".getBytes());
      
    • 或 Apache Commons Codec / Spring DigestUtils

  • 配置类不需要,直接在业务代码中调用即可

  • 注意事项

    • 如果用于密码存储,必须加盐 + 多轮迭代

BCrypt

  • 性质:单向加密(哈希 + 自动加盐 + 可调复杂度)

  • Spring Boot 支持:原生提供 BCryptPasswordEncoder

  • 使用方式

    • 可以直接在业务中 new 一个对象用:

      BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
      String hash = encoder.encode("password");
      boolean match = encoder.matches("password", hash);
      
    • 推荐写配置类注入 PasswordEncoder,方便 Spring Security 集成:

      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
      import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
      public class PasswordConfig {/*** BCryptPasswordEncoder 默认 cost = 10* cost 越大,计算越慢,安全性越高*/@Beanpublic PasswordEncoder bCryptPasswordEncoder() {return new BCryptPasswordEncoder(10); // 可以根据性能调整}
      }
      

      使用示例

      @Autowired
      private PasswordEncoder passwordEncoder;public void register(String rawPassword) {String encoded = passwordEncoder.encode(rawPassword);// 保存 encoded 到数据库
      }public boolean login(String rawPassword, String storedHash) {return passwordEncoder.matches(rawPassword, storedHash);
      }
      
  • 配置类推荐,但不是必须

    • 如果项目不使用 Spring Security,也可以直接 new BCryptPasswordEncoder()

Argon2(Argon2id)

  • 性质:现代密码哈希(内存硬化 + 自动加盐 + 可调复杂度)

  • Spring Boot 支持:Spring Security 5+ 原生提供 Argon2PasswordEncoder

  • 使用方式

    • 直接 new 使用:

      Argon2PasswordEncoder encoder = new Argon2PasswordEncoder();
      String hash = encoder.encode("password");
      boolean match = encoder.matches("password", hash);
      
    • 推荐写配置类注入 PasswordEncoder

      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
      import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
      public class PasswordConfig {/*** Argon2PasswordEncoder 参数说明:* saltLength: 盐长度(字节)* hashLength: 输出哈希长度(字节)* parallelism: 并行线程数* memory: 内存消耗 (KB)* iterations: 哈希迭代次数*/@Beanpublic PasswordEncoder argon2PasswordEncoder() {return new Argon2PasswordEncoder(16,       // salt length32,       // hash length1,        // parallelism65536,    // memory cost (64 MB)3         // iterations);}
      }

      使用示例

      @Autowired
      private PasswordEncoder passwordEncoder;public void register(String rawPassword) {String encoded = passwordEncoder.encode(rawPassword);// 保存 encoded 到数据库
      }public boolean login(String rawPassword, String storedHash) {return passwordEncoder.matches(rawPassword, storedHash);
      }
      
  • 配置类推荐

    • 方便全局统一使用,尤其是结合 Spring Security

总结

Spring Boot 项目中,选择合适的哈希/加密算法主要取决于用途安全性需求

算法类型输出长度安全性特点与适用场景Spring Boot 使用方式
MD5哈希算法128 位(16 字节)已不安全快速计算、雪崩效应强;适合文件校验、数据完整性检测DigestUtils.md5DigestAsHex() 调用即可,无需配置类
SHA 系列哈希算法160~512 位SHA-1 已不安全,SHA-2/3 安全可靠的消息摘要算法;文件校验、签名、JWT、加密辅助Java MessageDigest 或 Apache DigestUtils调用,无需配置类;用于密码需加盐+多轮
BCrypt密码哈希60 字符安全自动加盐、可调成本(cost)、不可逆;适合用户密码存储推荐创建配置类 PasswordEncoderBean;可直接 new BCryptPasswordEncoder()
Argon2密码哈希可变(Base64)高安全自动加盐、可调时间/内存/并行度;防 GPU/ASIC 攻击,现代推荐算法推荐创建配置类 PasswordEncoderBean,使用 Argon2PasswordEncoder,参数可自定义

建议

  1. 简单数据完整性(如文件校验、数据摘要)
    • 使用 MD5 或 SHA-2/3 即可
    • 不需要配置类,直接工具类调用
  2. 用户密码存储
    • 强烈建议使用 BCryptArgon2id
    • MD5、SHA-1、SHA-256 不安全,即使加盐也难抵抗 GPU 彩虹表攻击
    • 在 Spring Boot 项目中,建议通过 配置类统一注入 PasswordEncoder Bean,方便全局使用和与 Spring Security 集成
  3. 性能与安全平衡
    • BCrypt:成本因子(cost)调整计算复杂度
    • Argon2:可调 timeCostmemoryCostparallelism,更安全且支持并行

总结一句话

文件校验用 MD5/SHA,密码存储用 BCrypt/Argon2(推荐 Argon2id),密码算法最好通过配置类统一注入 PasswordEncoder,保证安全性与可维护性。

http://www.dtcms.com/a/463580.html

相关文章:

  • 昭通网站seo团队拓展
  • 卡盟网站建设公司高清品牌网站设计建设
  • 网站模板的制作怎么做北京朝阳区哪里有网站开发
  • 好的网站开发培训深圳住房和建设局网站办事跟踪
  • 班级网站的建设wordpress升级流程
  • 上海的设计网站有哪些内容查看网站服务器ip
  • 面试被问到query不规范,导致召回难度大,如何解决呢
  • wordpress建站怎么上传做pc端网站咨询
  • 做一些网站犯法么网络服务设备有哪些
  • 企业网站建设 新天地网络咸阳公司做网站
  • 多线程并发篇面试题
  • 网站版面结构广州企业如何建网站
  • 化妆品公司网站源码网页制作软件大全
  • 用win2003做网站本科专业 网站开发
  • 网站ome系统怎么做装修公司网站怎么做的
  • 婚纱摄影网站优化技巧php wordpress 代码模板
  • 公司网站维护价格表2023网站关键词堆砌
  • 咸阳网站建设xymokj南宁庄关键词推广优化方案
  • 如何做网站系统海口网站建设q479185700棒
  • 德州北京网站建设seo优化大公司排名
  • html5网站动态效果软件工程就业方向和前景
  • 个人网站模板 html5合肥营销网站建设公司
  • 多种大连网站建设如何更换wordpress域名
  • 建设银行北京分行招聘网站php做网站安全
  • cms 企业网站技能培训有哪些科目
  • 绍兴市工程建设网站wordpress过去指定分类文章
  • 如何把jQuery特效做网站背景用php做的旅游网站
  • 商标设计网站是哪个网站排名软件包年
  • 郑州市建设厅官方网站深圳品牌策划公司
  • 爱站小工具苏州专业网站建设