哈希算法相关知识总结

文章介绍了哈希算法的基本概念和特点,如相同的输入得到相同输出,不同的输入得到不同输出。讨论了哈希碰撞现象,并提供了MD5和SHA-1在Java中的实现示例。此外,文章还探讨了哈希算法在文件校验、密码存储中的应用,以及HMAC算法用于增强报文完整性的验证。最后,提到了使用第三方库实现RipeMD160算法的示例。
摘要由CSDN通过智能技术生成

哈希算法概念及特点

哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。
哈希算法最重要的特点就是:
●相同的输入一定得到相同的输出;
●不同的输入大概率得到不同的输出。
所以,哈希算法的目的:为了验证原始数据是否被篡改。

常见的哈希算法:::

算法

输出长度(位)

输出长度(字节)

MD5

128 bits

16 bytes

SHA-1

160 bits

20 bytes

RipeMD-160

160 bits

20 bytes

SHA-256

256 bits

32 bytes

SHA-512

512 bits

64 bytes

哈希碰撞

哈希碰撞指的是:

"AaAaAa".hashCode(); // 0x7460e8c0

"BBAaBB".hashCode(); // 0x7460e8c0

"通话".hashCode(); // 0x11ff03

"重地".hashCode(); // 0x11ff03

两个不同的输入得到了相同的输出

碰撞是不可避免的,是一定会出现的,因为输出的字节长度是固定的。

MD5和SHA-1

SHA-1也是一种哈希算法,它的输出是160 bits,即20字节。

在Java中使用SHA-1,和MD5完全一样,只需要把算法名称改为"SHA-1":

用MD5和SHA-1时,可以创建一个架包,然后再使用,会更加便捷!、

架包怎么创建嘞!

代码如下:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

//Hash算法(消息摘要算法)工具类
public class HashTools {
	//消息摘要对象
	private static MessageDigest digest;
	//构造方法私有
	private HashTools() {}
	//按照MD5进行消息摘要计算(哈希计算)
	public static String digestByMD5(String source) throws NoSuchAlgorithmException {
		digest = MessageDigest.getInstance("MD5");
		return handler(source);
	}
	
	//按照SHA-1进行消息摘要计算(哈希计算)
	public static String digestBySHA1(String source) throws NoSuchAlgorithmException {
		digest = MessageDigest.getInstance("SHA-1");
		return handler(source);
	}
	
	//通过消息摘要对象,处理加密内容
	private static String handler(String source) {
		digest.update(source.getBytes());
		byte[] bytes = digest.digest();
		String hash = bytesToHex(bytes);
		return hash;
	}
	
	
	

		//将字节数组转换为16进制字符串
		public static String bytesToHex(byte[] bytes) {
			StringBuilder ret = new StringBuilder();
			for(byte b:bytes) {
				//将字节值转换为2位十六进制字符串
				ret.append(String.format("%02x",b));
			}
			return ret.toString();
		}
	

}

怎么应用呢:

import java.security.NoSuchAlgorithmException;

//通过自定义工具类,完成对应加密处理
public class Demo09 {
	public static void main(String[] args) throws NoSuchAlgorithmException {
		//MD5加密
		String md5 = HashTools.digestByMD5("wbjxxmy");
		//sha-1加密
		String sha1 = HashTools.digestBySHA1("wbjxxmy");
		
		System.out.println("md5="+md5);
		System.out.println("sha1="+sha1);
	}

}

哈希算法的用途

1.校验下载的文件以及应用是否为正版。一般情况下,官方下载文件的地方会有一些MD5哈希值,然后我们只需要计算本地下载文件的哈希值,如果一样,证明没有问题,如果不一样,那二锅头可就不能保证你的文件应用是不是有问题了        !!

2.存储用户密码。可以防止彩虹表的攻击。预防彩虹表攻击的方法是什么嘞!EMMM...

加盐,没错就是salt,食用盐。但是作用可不一样哦。

具体代码如下:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
//通过随机加盐,解决彩虹表共计
public class Demo08 {
	public static void main(String[] args) {
		
		try {
			//y原始密码
			String password = "123456";
			//产生随机的盐值
			String salt = UUID.randomUUID().toString().substring(0,4);
			//创建基于SHA-1算法的消息摘要
			MessageDigest pwd = MessageDigest.getInstance("MD5");
			pwd.update(password.getBytes());//原始密码
			pwd.update(salt.getBytes());//盐值
			//计算加密结果,
			String aaa = HashTools.bytesToHex(pwd.digest());
			 
			System.out.println(aaa);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

Hmac算法

HMAC算法 是一种基于密钥的报文完整性的验证方法。HMAC算法利用哈希运算,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。其安全性是建立在Hash加密算法基础上的。它要求通信双方共享密钥、约定算法、对报文进行Hash运算,形成固定长度的认证码。通信双方通过认证码的校验来确定报文的合法性。HMAC算法可以用来作加密、数字签名、报文验证等。
具体应用代码如下:

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;

//Hmac算法
public class Demo10 {
	public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException  {
		String password = "wbjxxmy";
		//获取HmacMD5秘钥生成器
		KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
		//1.生成秘钥
		SecretKey key = keyGen.generateKey();
		System.out.println("秘钥:"+Arrays.toString(key.getEncoded()));
		System.out.println("秘钥长度(64字节):"+key.getEncoded().length);
		System.out.println("秘钥:"+HashTools.bytesToHex(key.getEncoded()));
		
		//2.使用秘钥,进行加密
		//获取HMac加密算法对象
		Mac mac = Mac.getInstance("HmacMD5");
		mac.init(key);//初始化秘钥
		mac.update(password.getBytes());//更新原始加密内容
		byte[] bytes = mac.doFinal();//加密处理,并获取加密结果
		String result = HashTools.bytesToHex(bytes);//加密结果处理成16进制字符串
		System.out.println("加密结果16进制字符串"+result);
		System.out.println("加密结果(字节长度16字节)"+bytes.length);
		System.out.println("加密结果(字节长度32字节)"+result.length());

		}

}
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Demo11 {
	public static void main(String[] args) {
		//原始密码
		String password = "wbjxxmy";
		
		//秘钥(字节数组)
		//byte[] keyBytes = {-6, 120, 7, 96, 30, -96, -58, 86, -70, 15, 106, -107, -3, 119, -48, -87, 27, -100, -45, 70, 77, -50, 1, 93, 114, 118, 65, -78, -71, 41, -121, 101, 15, -73, 14, 86, -97, 66, 9, 30, 43, 94, 117, -67, -29, 30, -119, 59, 6, -112, 48, 125, 4, -23, 107, 126, -14, 72, 106, 99, -106, -96, 70, 112};
		
		//秘钥(字符串)
		String keyStr = "451c60fff4f3c52e9f8e22e537bee82cb46f45e692a270d3728bbaf23550cb82af0baf1ddad3ec19e7893d13f18a386439dbfb452d4810921b8aa50a2de5d8ac";
		//f78a76fa7b8e2e79c19372ad2b7d7292
		//用于保存秘钥:秘钥长度为64字节
		byte[] keyBytes = new byte[64];
		
		for (int i = 0, k = 0; i < keyStr.length(); i+=2 ,k++) {
			String s = keyStr.substring(i,i+2);
			keyBytes[k] = (byte) Integer.parseInt(s,16);//转换成16进制byte值
		}
		
		
		
		//恢复秘钥(字节数组)、
		try {
			SecretKey key = new SecretKeySpec(keyBytes,"HmacMD5");
			
			//创建Hmac加密算法对象
			Mac mac =Mac.getInstance("HmacMD5");
			mac.init(key);//初始化秘钥
			mac.update(password.getBytes());
			String result = HashTools.bytesToHex(mac.doFinal());
			//a69f35cc658225d18915cd0bf1a37115
			System.out.println(result);
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
	}

}

使用第三方开源库提供的RipeMDR60消息摘要算法实现

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Arrays;

import org.bouncycastle.jce.provider.BouncyCastleProvider;


//使用第三方开源库提供的RipeMDR60消息摘要算法实现
public class Demo12 {
	public static void main(String[] args) throws NoSuchAlgorithmException {
		//注册BouncyCastlenBouncyCastleProvider通知类
		//将提供的消息摘要算法注册至Security
		Security.addProvider(new BouncyCastleProvider());
		          
		//获取RipeMD160算法的“消息摘要对象”(加密对象)
		MessageDigest ripeMd160 = MessageDigest.getInstance("RipeMD160");
		
		//更新原始数据
		ripeMd160.update("wbjxxmy".getBytes());
		
		//获取消息摘要(加密)
		byte[] result = ripeMd160.digest();
		
		//消息摘要的字节长度和内容
		System.out.println("加密结果(字节长度):"+result.length);//20字节=40个字符
		System.out.println("加密结果(字节内容):"+Arrays.toString(result));
		
		//16进制内容字符串
		String hex = new BigInteger(1, result).toString(16);
		System.out.println("加密结果(字符串长度):"+hex.length());//20字节=40个字符
		System.out.println("加密结果(字符串内容):"+hex);
	}

}

以上就是二锅头今天整理的哈希算法的相关知识还有代码了。。。

如果对你有帮助,记得支持二锅头,一键三连哦!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值