常见哈希算法总结

目录

哈希算法概述

常见的哈希算法:

MD5算法

 SHA-1算法:

 哈希算法的用途

校验下载文件

存储用户密码

Hmac MD5算法


哈希算法概述

哈希算法又称摘要算法,它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算法的目的:为了验证原始数据是否被篡改。

哈希算法的特点就是:

1.相同的输入一定得到相同的输出;

2.不同的输入大概率得到不同的输出。

常见的哈希算法:

算法输出长度(位)输出长度(字节)
MD5128bit16bytes
SHA-1160bit20bytes
RipeMD-160160bit20bytes
SHA-256256bit32bytes
SHA-512512bit64bytes

Java标准库提供了常用的哈希算法,并且有一套统一的接口。以MD5算法为例,看看如何对输入计算哈希:

MD5算法

	public static void main(String[] args) throws IOException {

		try {			
           //获取一个MessageDigest对象:
			MessageDigest digest = MessageDigest.getInstance("MD5");
			//把要加密的内容转换成字节数据
			byte[] simpledata = "hnczjtyrbl".getBytes();
			System.out.println("原始数据:"+Arrays.toString(simpledata));
			digest.update(simpledata);
			//获得加密后的数据:
			byte[] result = digest.digest();
			System.out.println("加密后的数据:"+Arrays.toString(result));
			//转换成十六进制的字符串
			StringBuilder sb = new StringBuilder();
			for(byte b:result) {
				sb.append(String.format("%x", b));
			}
			
			System.out.println("转换成16进制字符串:"+sb);
			System.out.println("长度:"+sb.length());
			} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

MD5算法先获得一个MessageDigest对象,然后用update()方法传入要加密内容的字节数组。然后通过digest()方法获得最终加密的结果。

 SHA-1算法:

SHA-1算法和MD5算法用法类似,不同的一点就是MD5加密的结果是一个长度为16的字节数组,而SHA-1加密的结果是一个长度为20的字节数组。

public static void main(String[] args) throws IOException {

		try {// 要加密的内容
			String password = "hdljdylzsx";
			// 创建一个MessageDigest对象:
			MessageDigest digest1 = MessageDigest.getInstance("SHA-1");
			// 更新要加密的数据
			digest1.update(password.getBytes());
			byte[] resultArray1 = digest1.digest();
			System.out.println("原始数据:" + Arrays.toString(password.getBytes()));
			// 加密后的结果
			System.out.println("加密后的结果:" + Arrays.toString(resultArray1));
			System.out.println("长度:" + resultArray1.length);
			StringBuilder sb = new StringBuilder();
			for (byte b : resultArray1) {
				sb.append(String.format("%x", b));
			}
			System.out.println("转换成16进制字符串:" + sb);
			System.out.println("长度:" + sb.length());

		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 哈希算法的用途

校验下载文件

因为相同的输入永远会的到相同的输出,因此,如果输入被修改了,得到的输出就会不同。我们在网站上下载软件的时候,经常会看到下载页显示MD5哈希值:

不存储用户的原始口令,那么如何对用户进行认证?方法是存储用户口令的哈希,例如,MD5。在用户输入原始口令后,系统计算用户输入的原始口令的MD5并与数据库存储的MD5对比,如果一致,说明口令正确,否则,口令错误。

如何判断下载到本地的软件是原始的、未经篡改的文件?我们只需要自己计算一下本地文件的哈希值,再与官网公开的哈希值对比,如果相同,说明文件下载正确,否则,说明文件已被篡改。

存储用户密码


哈希算法的另一个重要用途是存储用户口令。如果直接将用户的原始口令存放到数据库中,会产生极大的安全风险:
1.数据库管理员能够看到用户明文口令;
2.数据库数据一旦泄漏,黑客即可获取用户明文口令。

使用哈希口令时,还要注意防止彩虹表攻击。什么是彩虹表呢?上面讲到了,如果只拿到MD5,从MD5反推明文口令,只能使用暴力穷举的方法。然而黑客并不笨,暴力穷举会消耗大量的算力和时间。但是,如果有一个预先计算好的常用口令和它们的MD5的对照表,这个表就是彩虹表。如果用户使用了常用口令,黑客从MD5一下就能反查到原始口令:

当然,我们也可以采取特殊措施来抵御彩虹表攻击:对每个口令额外添加随机数,这个方法称之为“加盐”。这样即使数据库泄露,黑客也不能获得用户明文。

Hmac MD5算法

public static void main(String[] args) {
		String password = "yyzsbjr";
		try {
			// 生成秘钥
			// 秘钥生成器keyGenerator
			KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
			//生成秘钥key
			SecretKey key = keyGen.generateKey();
			byte[] keyByteArray = key.getEncoded();
			System.out.println("秘钥长度" + keyByteArray.length);
			StringBuilder sb = new StringBuilder();
			for (byte b : keyByteArray) {
				sb.append(String.format("%02x", b));
			}
			System.out.println(sb);

			System.out.println(sb.length());
			Mac mac = Mac.getInstance("HmacMD5");
			mac.init(key);
			mac.update(password.getBytes());
			byte[] resultByteArray = mac.doFinal();
			System.out.println("加密结果:" + resultByteArray.length + "字节");
			StringBuilder resultStr = new StringBuilder();
			for (byte b : resultByteArray) {
				resultStr.append(String.format("%02x", b));

			}
			System.out.println("加密长度" + resultStr.length());
			System.out.println("加密内容:" + resultStr);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

和MD5相比,使用HmacMD5的步骤是:
1.通过名称HmacMD5获取KeyGenerator实例;
2.通过KeyGenerator创建一个SecretKey实例;
3.通过名称HmacMD5获取Mac实例;
4.用SecretKey初始化Mac实例;
5.对Mac实例反复调用update(byte[])输入数据;
6.调用Mac实例的doFinal()获取最终的哈希值。得到加密后的结果。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

磨剑斩秋招

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值