Java 如何加密密码?

2025年5月8日 | 阅读 7 分钟

每个软件应用程序都需要用户名和密码来验证合法用户。用户名可以是电子邮件 ID 或只是字符组合。但在创建密码时,必须非常小心。因为任何拥有合法凭证的人都可以进入系统并访问信息。

加密密码的必要性

当用户设置密码时,它会以纯文本形式存储在数据库中。直接将纯文本存储在数据库中根本不安全。黑客可能会破解系统并从数据库中窃取密码。

为确保用户密码的安全,会使用不同的加密技术对其进行加密。使用各种加密技术,明文密码将以加密形式存储在数据库中。有许多方法可用于加密密码。但哈希是其中最受欢迎的加密技术之一。

Java 安全哈希技术

加密的哈希值是根据用户提供的明文密码使用某些算法生成的。Java 编程支持多种哈希技术来加密密码。

MD5 哈希技术

MD5(Message Digest,消息摘要)是一种非常流行的哈希算法。它是一种加密哈希函数,可生成 128 位哈希值。此算法在 Java 编程的 `java.security` 包下定义。

PassEncTech1.java

输出

Plain-text password: myPassword
Encrypted password using MD5: deb1536f480475f7d593219aa1afd74c

上面的代码显示了 `java.security` 包中 `MessageDigest` 类的实现。MD5 返回一个字节数组,需要将其转换为可读的十六进制格式。

MD5 哈希技术易于实现且速度快,但它也容易受到暴力破解攻击或字典攻击。

SHA256

SHA 是安全哈希算法(Secure Hash Algorithm)。它使用一种加密函数,该函数接收 32 位明文密码并将其转换为固定大小的 256 位哈希值。此哈希技术使用 `java.security` 包的 `MessageDigest` 类实现。

它是一种单向加密技术。一旦密码被加密,就无法解密回原始密码。

PassEncTech2.java

输出

myPassword : 76549b827ec46e705fd03831813fa52172338f0dfcbd711ed44b81a96dac51c6

hashtrial : d3e3224a59d69e9a000f1ce6782cb6a8be1eb3155610ff41bffbcbc95adc5d7

上面的代码使用 `MessageDigest` 类的实例来生成 `SHA256` 的哈希。SHA256 返回一个字节数组,需要将其转换为可读的十六进制格式。最后,显示加密的哈希值。

SHA512 MD5 哈希技术

SHA512 使用一种加密函数,该函数接收 64 位明文密码并将其转换为固定大小的 512 位哈希值。此哈希技术也使用 `java.security` 包的 `MessageDigest` 类实现。

PassEncTech2.java

输出

myPassword : 450ad03db9395dfccb5e03066fd7f16cfba2b61e23d516373714471459052ec90a9a4bf3a151e600ea8aaed36e3b8c21a3d38ab1705839749d130da4380f1448

hashtrial : 9520ea1a8d60d23334e6d59acebd587de6fec1e53db5836f467096c540ae60f7c85e9fbc90856dee9d6563609b8786b03b47892af0bad44bdcab2206f22df5cb

上面的代码使用 `MessageDigest` 类的实例来生成 `SHA512` 的哈希。SHA512 返回一个字节数组,需要将其转换为可读的十六进制格式。最后,显示加密的哈希值。

基于密码的加密(使用 Salt 和 Base64)

基于密码的加密技术使用明文密码和 salt 值来生成哈希值。然后将哈希值编码为 Base64 字符串。Salt 值包含使用 `java.util` 包中 `Random` 类的实例生成的随机数据。

以下程序演示了使用 salt 和 base64 进行密码加密。

PassEncTech4.java

输出

Plain text password = myNewPass123
Secure password = sA0jNGQTrAfMUiqrB++bMKTU55ThdFCl16ZZTIXwD2M=
Salt value = n7d9MPQFXxDqzT6onmong3hQt8Nyko
Password Matched!!

在上面的代码中,定义了两个类。

  1. `PassEncTech4` 类包含程序的驱动代码。它使用给定的明文密码生成 salt 值和加密密码。并通过 `verifyUserPassword()` 返回的值进行验证。
  2. 在 `PassBasedEnc` 类中,定义了 4 个方法。第一个方法是 `getSaltvalue()`,它使用 `util` 包中的 `Random` 类生成值。然后定义了 `hash()`,其返回类型为字节数组。`generateSecurePassword()` 使用明文密码和 salt 值以及 `hash()` 方法。最后,使用 `verifyUserPassword()` 方法匹配两个密码。

破解哈希的技巧

哈希值容易受到攻击者的不同攻击。其中一些在下面提到:

  1. **暴力破解攻击(Brute force attack):** 在暴力破解攻击中,攻击者尝试多种密码组合,希望其中一个组合能匹配,从而能够进入系统。
    为避免此类攻击,密码应使用字母、数字和符号的组合。另一种方法是设置固定数量的无效尝试次数,之后要求进行人工验证,例如验证码。
  2. **字典攻击(Dictionary attack):** 字典攻击是暴力破解攻击的增强版本。在此技术中,尝试使用多种可能性来解密加密的密码,例如字典中的单词。
  3. **彩虹表(Rainbow tables):** 该技术涉及一个预先计算好的用于反转加密哈希函数的彩虹表。彩虹表用于发现一定长度和有限数量字符的明文密码。因此,它使用旁路表来减少存储使用并提高攻击速度。