Hash加密算法总结

您所在的位置:网站首页 模糊哈希算法 Hash加密算法总结

Hash加密算法总结

2024-05-31 06:26| 来源: 网络整理| 查看: 265

一、概述

        Hash加密算法是一种将任意长度的消息压缩成固定长度散列值的算法。它的特点是快速、不可逆和安全。Hash加密算法被广泛用于数字签名、数据完整性验证等信息安全领域。本文将介绍Hash加密算法的基本原理、常用算法和应用场景。

1.1基本原理

        Hash加密算法通过将任意长度的消息输入到算法中,经过一系列计算得到一个固定长度的Hash值。Hash值可以看作是消息的指纹,具有唯一性和不可逆性。对于相同的消息,执行相同的Hash算法得到的Hash值是相同的,但即使是输入消息的微小变化也会导致Hash值的巨大变化。因此,Hash加密算法可以用于验证数据完整性和数字签名等场景。

二、哈希碰撞

        哈希碰撞是指:两个不同的输入得到了相同的输出。

        例如:

"AaAaAa".hashCode(); // 0x7460e8c0 "BBAaBB".hashCode(); // 0x7460e8c0 "通话".hashCode(); // 0x11ff03 "重地".hashCode(); // 0x11ff03

         碰撞能不能避免?答案是不能。碰撞是一定会出现的,因为输出的字节长度是固定的, String 的 hashCode() 输出是 4 字节整数,最多只有 4294967296 种输出, 但输入的数据长度是不固定的,有无数种输入。所以,哈希算法是把一个无限的输入 集合映射到一个有限的输出集合,必然会产生碰撞。 碰撞不可怕,我们担心的不是碰撞,而是碰撞的概率,因为碰撞概率的高低关系 到哈希算法的安全性。一个安全的哈希算法必须满足: 碰撞概率低; 不能猜测输出。 不能猜测输出是指:输入的任意一个 bit 的变化会造成输出完全不同,这样就很难从输出反推输入(只能依靠暴力穷举)。        

三、常用算法

先创建一个工具类,用于将加密结果转换成16进制字符串:

package EnConde.MD5; public class HashTools { private HashTools(){} public static String bytesToHex(byte[] bytes){ StringBuilder ret = new StringBuilder(); for (byte b : bytes) { ret.append(String.format("%02x", b)); } return ret.toString(); } } 2.1MD5算法

        MD5算法是一种广泛使用的Hash加密算法。它的输出为128位二进制数,通常用32位十六进制数表示。MD5算法是基于MD4算法的改进版,具有更强的安全性和较快的运算速度。但是,由于其安全性不够高,不建议在安全性要求较高的场景中使用。

package EnConde.MD5; import java.security.MessageDigest; import java.util.Arrays; public class Test1 { public static void main(String[] args) throws Exception{ //创建基于MD5算法的消息摘要对象 MessageDigest md5 =MessageDigest.getInstance("MD5"); //更新原始对象 md5.update("dadad".getBytes()); //获取加密后的结果 byte[] digestBytes = md5.digest(); System.out.println("加密结果:" + Arrays.toString(digestBytes)); System.out.println("结果(字符串):" + HashTools.bytesToHex(digestBytes)); System.out.println("长度:" + digestBytes.length); } } 加密结果:[-31, 10, -36, 57, 73, -70, 89, -85, -66, 86, -32, 87, -14, 15, -120, 62] 结果(字符串):e10adc3949ba59abbe56e057f20f883e 长度:16  2.1.1加盐

        哈希算法的一个重要途径就是存储用户密码等重要信息,用户登陆时系统会将用户输入的密码进行加密计算,然后与数据库中存储的加密信息比对,如果相同则密码正确,反之密码错误。这样做即使储存账号密码的数据库泄露,他人也无法知道用户的原始密码。但是要预防彩虹表攻击。

        彩虹表攻击(Rainbow Table Attack)是一种密码破解技术,它通过预先生成大量的可能性密码,存储在彩虹表中,然后与目标系统的加密密码匹配,以找出密码的明文。

        彩虹表攻击是一种离线攻击方式,攻击者不需要直接与目标系统进行交互,而是使用预先生成的彩虹表进行计算,以枚举可能的密码。因此,彩虹表攻击不需要破解系统的加密算法,而是利用了密码长度和复杂度不足的弱点。

        为了防止彩虹表攻击,可以采取一些措施,如使用强密码,使用盐值(salt)等。盐值是一个随机的字符串,与密码结合使用,使得相同的密码在不同的系统上产生不同的加密结果,从而增加了彩虹表攻击的难度。

package EnConde.MD5; import java.security.MessageDigest; import java.util.UUID; public class Test3 { public static void main(String[] args) throws Exception{ String password = "123456"; //盐值 String random = UUID.randomUUID().toString().substring(0,4); //创建基于MD5算法的消息摘要对象 MessageDigest md5 = MessageDigest.getInstance("MD5"); //加盐 md5.update(password.getBytes()); md5.update(random.getBytes()); byte[] ret = md5.digest(); System.out.println("加密结果:" + HashTools.bytesToHex(ret)); } } 加密结果:b70c612966fa90483b9be96ddc90f118

可以看到与加盐前的加密结果不同,更加提高了安全性。

但每次加密的结果都与上一次不同,这是因为每次加的盐值不同,所以加盐后要把盐值也存储到数据库中。

2.2SHA算法

        SHA算法是一系列Hash算法的总称,包括SHA-1、SHA-2和SHA-3等。其中,SHA-1算法输出160位的Hash值,SHA-2算法输出256、384或512位的Hash值,SHA-3算法则输出224、256、384或512位的Hash值。SHA-2算法是目前最广泛使用的Hash加密算法之一,具有较高的安全性和可靠性。

package EnConde.SHA1; import EnConde.MD5.HashTools; import java.security.MessageDigest; import java.util.Arrays; public class Test1 { public static void main(String[] args) throws Exception{ String password = "123456"; //创建基于SHA1算法的消息摘要对象 MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); //更新原始对象 sha1.update(password.getBytes()); //获取加密后的结果 byte[] ret = sha1.digest(); System.out.println("加密结果:" + Arrays.toString(ret)); System.out.println("结果(字符串):" + HashTools.bytesToHex(ret)); System.out.println("长度:" + ret.length); } } 加密结果:[124, 74, -115, 9, -54, 55, 98, -81, 97, -27, -107, 32, -108, 61, -62, 100, -108, -8, -108, 27] 结果(字符串):7c4a8d09ca3762af61e59520943dc26494f8941b 长度:20

        具体算法与MD5算法大同小异,只是将getInstance()中的MD5改成SHA-1,SHA-256,SHA-512等也是同理,因为这些都是java标准库支持的哈希算法。

        可以看到与MD5算法最大的区别就是固定长度不同。

2.3RipeMD160算法

        RipeMD160算法是一种安全哈希函数,用于将任意长度的数据(字符串、文件等)压缩成160位的哈希值。它是对RIPEMD算法的改进和升级,于1996年面向欧洲信息技术标准委员会(CEN)提出,并获得了国际标准化组织(ISO)的认可。

        RipeMD160算法与MD5、SHA-1等哈希算法相比,具有更大的哈希值输出长度、更高的安全性和更好的性能。同时,它也可以应用于数字签名、数据完整性验证和消息认证等领域。

        但java标准库不支持该算法,所以需要导入jar(bcprov-jdk15on-1.70.jar)。

package EnConde.RipeMD160; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.math.BigInteger; import java.security.MessageDigest; import java.security.Security; import java.util.Arrays; public class Test1 { public static void main(String[] args) throws Exception{ //注册BouncyCastleBouncyCastleProvider通知类 //将提供的消息摘要算法注册至Security Security.addProvider(new BouncyCastleProvider()); //获取RipeMD160算法的加密对象 MessageDigest ripeMd160 = MessageDigest.getInstance("RipeMD160"); //更新原始数据 ripeMd160.update("123456".getBytes()); //获取消息摘要(加密) byte[] ret = ripeMd160.digest(); //消息摘要的字节长度和内容 System.out.println("结果(长度):" + ret.length); System.out.println("内容:" + Arrays.toString(ret)); //16进制内容字符串 String hex = new BigInteger(1, ret).toString(16); System.out.println("结果(长度):" + hex.length()); System.out.println("内容:" + hex); } } 结果(长度):20 内容:[-68, -7, 122, -57, 43, -122, 116, 20, -96, 11, 84, -80, -36, 64, -32, -128, 82, -76, 104, 79] 结果(长度):40 内容:bcf97ac72b867414a00b54b0dc40e08052b4684f 三、应用场景 3.1数据完整性验证

        Hash加密算法可以用于验证数据的完整性。发送方对数据计算Hash值,并将其发送给接收方。接收方对接收到的数据计算Hash值,如果两个Hash值相同,则可以确认数据没有被篡改。这种应用场景在互联网数据传输中非常常见,例如网站提供下载的软件文件通常会提供md5或sha1校验值,让用户利用Hash算法验证文件的完整性。

3.2数字签名

        Hash加密算法可以用于数字签名,即对数字信息进行签名,让接收方确认发送方的身份和内容的确是由发送方所发出的。发送方对消息计算Hash值,并使用自己的私钥对Hash值进行加密,形成数字签名并发送给接收方。接收方对消息计算Hash值,并使用发送方的公钥对数字签名进行解密,得出Hash值并与接收到的Hash值进行比对。如果两个Hash值相同,则确认发送方的身份和消息的完整性,数字签名有效。

四、总结        

        Hash加密算法是一种快速、不可逆和安全的算法,被广泛应用于数字签名、数据完整性验证等信息安全领域。常见的Hash算法包括MD5和SHA算法。Hash算法的应用场景包括数据完整性验证和数字签名等。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3