Java MD5哈希示例

MD5 是一种加密的消息摘要算法,可产生128位的哈希值。哈希函数采用任意大小的数据,并生成固定长度的哈希值。散列是一种单向函数,无法从散列中获取原始消息,并且两个不同的字符串都不能具有相同的散列值。在本文中,我们将学习使用MessageDigest,  Guava 和 Apache Commons进行Java MD5哈希处理。

散列使我们能够验证通过通道传输的消息是否已被篡改,如果输入发生了很小的变化,则产生的散列将有所不同。尽管由于发现了多个漏洞,MD5不被认为是一种好的加密算法,但是它的校验和足以验证文件的完整性。

在进行编码之前,让我们首先对校验和有一些基本的了解

什么是校验和?

您是否曾经从互联网上下载某些文件(例如更新,补丁等)时注意到过,它们会提供校验和MD5SHA256等,这将是很长的乱序字符序列,称为校验和用于特定文件。校验和可确保通过网络传输的文件的完整性。

校验和是使用诸如MD5,SHA1,SHA256等哈希算法计算的。即使文件进行了很小的修改,文件的校验和也会更改,下载文件的用户将计算已下载文件的校验和,并且两者应该匹配,如果不匹配,那么我们可以假设文件已被篡改。

让我们看看到例如,我们有两个文件下面的内容为文件1的“Hello World”和内容文件2的“Hello World”。。我们在file2中添加的所有内容都是一个点(。),但所得的校验和不同。

文件1校验和:b10a8db164e0754105b7a99be72e3fe5

文件2校验和:d7527e2509d7b3035d23dd6701f5d8d0

Java MD5哈希示例1

让我们深入研究代码

Java MD5散列示例

package MD5HashingExample;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Example {
	public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		String input = "JavaInterviewPoint";

		// MessageDigest instance for MD5
		MessageDigest md = MessageDigest.getInstance("MD5");

		// Update MessageDigest with input text in bytes
		md.update(input.getBytes(StandardCharsets.UTF_8));

		// Get the hashbytes
		byte[] hashBytes = md.digest();

		// Convert hash bytes to hex format
		StringBuilder sb = new StringBuilder();
		for (byte b : hashBytes) {
			sb.append(String.format("%02x", b));
		}

		// Print the hashed text
		System.out.println(sb.toString());
	}
}
  • 通过将“ MD5”作为参数传递给getInstance()方法,为MD5哈希函数创建MessageDigest实例

MessageDigest md = MessageDigest.getInstance(“ MD5”);

  • 获取输入文本的字节,并将其传递到消息摘要实例的update()方法。

md.update(input.getBytes(StandardCharsets.UTF_8));

注意:使用密码术时,请始终确保指定要表示字节的编码。简单来说,如果您使用的是getBytes(),它将使用平台默认的编码。并非所有的操作系​​统都使用相同的默认编码。

  • 摘要()方法执行实际的散列,并返回传递给它的文本的哈希版本。

byte [] hashBytes = md.digest();

  • 最后,将hashBytes转换为十六进制格式

for(字节b:hashBytes){

      sb.append(String.format(“%02x”,b)); }

用Java获取文件的MD5校验和

在上面的代码中,我们已经为简单的输入字符串计算了MD5哈希值。在现实世界中,大多数MD5都将用于计算文件的校验和,例如zip,exe,iso等。

例如,如果由于网络问题或篡改而导致文件下载不正确,则您知道原始文件的校验和以及已下载文件的运行校验和。如果结果校验和匹配,则您拥有的文件是相同的(如果文件没有损坏或被篡改)。

现在,让我们看一下获取文件的MD5校验和的代码。

package MD5HashingExample;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Example_File {
	public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
		// MessageDigest instance for MD5
		MessageDigest md = MessageDigest.getInstance("MD5");

		byte[] fileBytes = Files.readAllBytes(Paths.get("D:\\temp.txt"));

		// Get the hashbytes
		byte[] hashBytes = md.digest(fileBytes);

		// Convert hash bytes to hexadecimal
		StringBuilder sb = new StringBuilder();
		for (byte b : hashBytes) {
			sb.append(String.format("%02x", b));
		}

		// Print the hashed text
		System.out.println(sb.toString());
	}
}
  • 通过将“ MD5”作为参数传递给getInstance()方法,为MD5哈希函数创建MessageDigest实例

MessageDigest md = MessageDigest.getInstance(“ MD5”);

  • 使用readAllBytes()中的文件类来获取fileBytes

byte [] fileBytes = Files.readAllBytes(Paths.get(“ D:\\ temp.txt”));

  • 通过fileBytes摘要()消息摘要实例,它返回的方法MD5哈希所述的文件

byte [] hashBytes = md.digest(fileBytes);

用盐保护MD5哈希

尽管MD5被广泛使用,但它很容易出现哈希冲突弱点。通过使用Lookup表Rainbow表,黑客可以轻松地识别密码,为了缓解这一问题,我们可以在哈希之前添加

Salt是固定长度的安全随机字符串,在散列之前将其添加到密码中,因此对于相同的密码,散列将有所不同。

现在,让我们看看如何使用Salt保护MD5哈希

package MD5HashingExample;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class MD5ExampleWithSalt {
	public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		String input = "JavaInterviewPoint";

		// MessageDigest instance for MD5
		MessageDigest md = MessageDigest.getInstance("MD5");

		// Generate the random salt
		SecureRandom random = new SecureRandom();
		byte[] salt = new byte[16];
		random.nextBytes(salt);

		// Passing the salt to the digest for the computation
		md.update(salt);

		// Update MessageDigest with input text in bytes
		md.update(input.getBytes(StandardCharsets.UTF_8));

		// Get the hashbytes
		byte[] hashBytes = md.digest();

		// Convert hash bytes to hexadecimal
		StringBuilder sb = new StringBuilder();
		for (byte b : hashBytes) {
			sb.append(String.format("%02x", b));
		}

		// Print the hashed text
		System.out.println(sb.toString());
	}
}

我们将为SecureRandom类创建一个新实例,nextByte()方法将生成随机盐。

SecureRandom random =新的SecureRandom();
字节[]盐=新的字节[16];
random.nextBytes(盐);

这段代码每次为相同的输入文本生成不同的哈希

运行1: 85a9df6cdbc31b7dd89a2165203e794b

运行2: f2cc604967e2206f5f1513a4e31839dc

猜你喜欢

转载自blog.csdn.net/allway2/article/details/115349671
今日推荐