md5介绍
md5(message-digest algorithm 5)是一种广泛使用的哈希算法,其输出结果是一个128位的二进制数,通常以32位十六进制数的形式表示。因此,md5的输出结果可以表示为一个32位的字符串。
md5算法常用于数据完整性验证、密码加密等场景,通常将输入的数据经过md5处理后,得到一个32位的摘要(digest),该摘要作为数据的唯一表示,可以用于验证数据的完整性或作为密码的加密存储。需要注意的是,由于md5算法本身存在安全性问题,已经不再推荐用于密码加密等安全场景,而应该使用更加安全的算法,如sha-2、bcrypt等。
md5(message digest algorithm 5)是一种哈希函数,而不是对称加密算法。md5 用于产生一个称为消息摘要(message digest)的固定大小的哈希值,通常是 128 位。md5 不是加密算法,因为哈希值是不可逆的,即无法从哈希值还原出原始数据。
对称加密算法是一种使用相同密钥进行加密和解密的算法,例如 des(data encryption standard)、aes(advanced encryption standard)等。与对称加密不同,哈希函数通常是单向的,只能从原始数据计算出哈希值,而无法从哈希值还原出原始数据。
安全性:md5 已经被认为不再安全,因为它容易受到碰撞攻击。对于需要安全性的应用(如密码存储),建议使用更强的散列算法(如 sha-256)和适当的安全实践(如加盐)。
性能:虽然 md5 在性能上表现良好,但现代安全需求通常需要更强的散列算法。
md5(message digest algorithm 5)是一种广泛使用的加密散列函数,主要用于生成数据的唯一摘要值(哈希值)。md5 的底层实现涉及多个复杂的步骤和算法。以下是 md5 的底层工作原理和关键概念:
- 基本概念
散列函数:md5 是一种散列函数,用于将任意长度的输入数据(消息)映射为固定长度的输出(128 位,或 16 字节)的哈希值。
不可逆性:md5 生成的哈希值理论上无法逆推出原始输入数据。
固定长度:无论输入数据的长度如何,md5 总是生成一个 128 位的哈希值。 - md5 的步骤
md5 的底层算法包括以下主要步骤: - 初始化
md5 使用四个 32 位的初始常量(a、b、c、d)作为计算的起始值:
( a = 0x67452301 )
( b = 0xefcdab89 )
( c = 0x98badcfe )
( d = 0x10325476 )
这些常量用于初始化 md5 的内部状态。 - 填充
将输入数据填充到 512 位的倍数。填充过程包括:
填充位:在输入数据的末尾添加一个 1 位的标志位,表示数据结束。
填充零:在标志位后添加零,直到数据长度接近 512 位。
附加长度:在数据末尾附加原始数据的长度(以位为单位),以 64 位表示。填充后的数据总长度为 512 位的倍数。 - 数据分块
将填充后的数据分成 512 位的块,每个块被进一步分成 16 个 32 位的子块(总共 64 个字节)。 - 处理每个数据块
对于每个 512 位的数据块,执行以下步骤:
扩展:将 16 个 32 位子块扩展为 64 个 32 位的子块,使用非线性函数进行处理。
轮次:md5 使用 64 轮的运算,每一轮使用不同的非线性函数(f、g、h、i)和常量(t[i])。每轮的运算包括:
非线性函数:f(x, y, z)、g(x, y, z)、h(x, y, z)、i(x, y, z)
常量:t[i] 是一组预定义的常量,与输入数据和轮次相关。
位运算:使用位移和按位与、或、异或等运算来更新内部状态(a、b、c、d)。
数据混合:将数据块与当前的内部状态进行混合。 - 输出
将最后一个数据块的处理结果(a、b、c、d)连接起来,生成 128 位(16 字节)的哈希值。 - md5 算法的详细步骤
填充:
在原始消息末尾添加 1 位的 1。
添加足够的 0,使得消息长度(包括填充的部分)为 448 位(512 位的前 448 位),即还需填充 0 到 64 位数据块的长度。
添加 64 位的消息长度,作为填充的最后部分,确保最终消息长度为 512 位的倍数。
初始化变量:
初始化 a、b、c、d 为常量值。
处理数据块:
将每个数据块分成 16 个 32 位的子块,使用特定的非线性函数和常量进行处理。
进行 64 轮的运算,更新 a、b、c、d 的值。
输出结果:
将 a、b、c、d 的最终值转换为 128 位的哈希值,通常以 16 进制表示。 - md5 的应用
数据完整性检查:通过比较文件的 md5 哈希值,可以检测文件是否被篡改。
密码存储:在数据库中存储密码的 md5 哈希值,而不是明文密码(注意:不建议仅使用 md5 存储密码,因为它已被证明不够安全)。 - 安全性
虽然 md5 曾被广泛使用,但由于其安全性问题,如碰撞攻击(即不同的输入可以产生相同的哈希值),它已不再被认为是安全的。对于需要更高安全性的应用,建议使用更强的哈希函数,如 sha-256 或 sha-3。
总结
md5 是一种将输入数据映射到固定长度哈希值的散列函数。其底层实现包括数据填充、分块、处理和最终输出四个主要步骤。尽管 md5 在许多应用中曾被广泛使用,但由于安全性问题,现如今建议使用更安全的哈希算法。
java 中实现 md5 加密方式
这三种方法都能有效地生成 md5 哈希。选择适合你项目需求的方式,如果已经使用了 apache commons codec 或 guava,可以直接利用它们的功能;如果只是简单的 md5 加密需求,使用 messagedigest 是最直接的方法。
在 java 中实现 md5 加密可以通过多种方式。
方法一:使用 messagedigest
这是最基本的方式,使用 java 内置的 messagedigest 类。
示例代码:
import java.security.messagedigest; import java.security.nosuchalgorithmexception; public class md5usingmessagedigest { public static string md5(string input) { try { messagedigest md = messagedigest.getinstance("md5"); byte[] messagedigest = md.digest(input.getbytes()); stringbuilder hexstring = new stringbuilder(); for (byte b : messagedigest) { string hex = integer.tohexstring(0xff & b); if (hex.length() == 1) { hexstring.append('0'); } hexstring.append(hex); } return hexstring.tostring(); } catch (nosuchalgorithmexception e) { throw new runtimeexception(e); } } public static void main(string[] args) { string input = "hello, world!"; system.out.println("md5 hash: " + md5(input)); } }
方法二:使用 apache commons codec
apache commons codec 是一个流行的库,提供了便捷的工具类进行编码和解码。
示例代码:
首先,确保在项目中添加 apache commons codec 的依赖:
<dependency> <groupid>commons-codec</groupid> <artifactid>commons-codec</artifactid> <version>1.15</version> <!-- 检查最新版本 --> </dependency>
然后可以使用以下代码:
import org.apache.commons.codec.digest.digestutils; public class md5usingcommonscodec { public static void main(string[] args) { string input = "hello, world!"; string md5hash = digestutils.md5hex(input); system.out.println("md5 hash: " + md5hash); } }
方法三:使用 guava
google 的 guava 库也提供了简单的 md5 加密功能。
示例代码:
首先,确保在项目中添加 guava 的依赖:
<dependency> <groupid>com.google.guava</groupid> <artifactid>guava</artifactid> <version>31.0.1-jre</version> <!-- 检查最新版本 --> </dependency>
然后可以使用以下代码:
import com.google.common.hash.hashing; import java.nio.charset.standardcharsets; public class md5usingguava { public static void main(string[] args) { string input = "hello, world!"; string md5hash = hashing.md5() .hashstring(input, standardcharsets.utf_8) .tostring(); system.out.println("md5 hash: " + md5hash); } }
方法四:spring核心包
import org.springframework.util.digestutils; import org.springframework.web.bind.annotation.getmapping; import org.springframework.web.bind.annotation.requestparam; import org.springframework.web.bind.annotation.restcontroller; @restcontroller public class hashcontroller { @getmapping("/md5") public string getmd5(@requestparam string input) { return digestutils.md5digestashex(input.getbytes()); } }
md5util
package com.maxvision.common.util; import lombok.extern.slf4j.slf4j; import java.security.messagedigest; @slf4j public class md5util { private static string bytearraytohexstring(byte[] b) { stringbuilder resultsb = new stringbuilder(); for (byte value : b) { resultsb.append(bytetohexstring(value)); } return resultsb.tostring(); } private static string bytetohexstring(byte b) { int n = b; if (n < 0) { n += 256; } int d1 = n / 16; int d2 = n % 16; return hex_digits[d1] + hex_digits[d2]; } /** * 用utf8编码进行md5加密 * * @param origin 原字符串 * @return 加密后字符串 */ public static string md5encode(string origin) { return md5encode(origin, "utf-8"); } public static string md5encode(string origin, string charsetname) { string resultstring = null; try { resultstring = origin; messagedigest md = messagedigest.getinstance("md5"); if (charsetname == null || "".equals(charsetname)) { resultstring = bytearraytohexstring(md.digest(resultstring.getbytes())); } else { resultstring = bytearraytohexstring(md.digest(resultstring.getbytes(charsetname))); } } catch (exception ignored) { } return resultstring; } private static final string[] hex_digits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; }
以上就是java实现md5加密的四种方式的详细内容,更多关于java md5加密的资料请关注代码网其它相关文章!
发表评论