只加密不解密的哈希算法(超详细版)

文章介绍了哈希算法的基本概念,包括其作为数据校验和完整性验证的用途,以及MD5、SHA系列等常见哈希算法。讨论了哈希碰撞问题和安全哈希算法应具备的特性。还提供了Java代码示例,展示了如何实现MD5和SHA家族的哈希加密,并提到了RipeMD160算法的实现需要第三方库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、哈希算法的简述

  • 概念

哈希算法(Hash Algorithm)是一种将任意长度的消息压缩到一个固定长度的摘要(digest)的函数。

  • 主要应用

 哈希算法的最主要的应用是对于一段数据,通过一定的算法,生成一个固定长度的哈希值,这个哈希值通常用于数据校验、数据完整性验证等领域。

  • 常见算法

  1. MD5---Message Digest Algorithm 5
  2. SHA-1---Secure Hash Algorithm 1
  3. SHA-256---Secure Hash Algorithm 256
  4. SHA-512---Secure Hash Algorithm 512
  5. RipeMD160
  •  特点

  1.  相同的输入一定会得到相同的输出
  2.  不同的输入大概率得到不同的输出。
  3.  给定的哈希值无法反向推出原始输入内容

 二、哈希碰撞

  • 概念

不同的输入得到了相同的输出称为哈希碰撞。这种情况是避免不了的,因为输出的哈希数据长度是固定的(最多只有4294967296种输出)但是输入的数据长度确实不固定的,有无数种输入。

  • 安全的哈希算法需要满足

  1. 抗碰撞性:相同的输入应该得到相同的输出,不同的输入应该尽可能得到不同的输出,即使输入之间只有微小的差异
  2. 无法逆推性:不应该能够通过哈希输出结果推导出输入。
  3. 抗修改性:输入的任何改动都应该导致输出的改动,且无法通过修改输出来推导出修改后的输入。

三、哈希算法的常见算法代码实现 

  • MD5---Message Digest Algorithm 5

  1. 中文加密
    //创建基于MD5的消息摘要对象
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    //更新原始数据
    md5.update("何事西风悲画扇".getBytes());
    //获得加密数据
    byte[] digestBytes = md5.digest();
    System.out.println("加密后的结果:"+Arrays.toString(digestBytes));
    System.out.println("加密后的结果(16进制):"+Hashtools.BytestoHex(digestBytes));
    System.out.println("加密结果长度:"+digestBytes.length);
    		
    //1、何事西
    //2、风悲画扇
    //分两次更新数据只要顺序相同获得的加密结果也是一样的
    
  2.  图片加密 
//获取图片信息
byte[] bs = Files.readAllBytes(Paths.get("D:\\3yue\\vv.jpg"));
//创建基于MD5的基本摘要信息
MessageDigest digest = MessageDigest.getInstance("MD5");
//更新数据
digest.update(bs);
//获得加密数组结果并输出
byte[] digestBytes = digest.digest();
System.out.println("加密后的结果:"+Arrays.toString(digestBytes));
//此处为一个Hashtools类写有BytestoHex
//是一个将数据转换为16进制的方法
System.out.println("加密后的结果(16进制):"+Hashtools.BytestoHex(digestBytes));
System.out.println("加密结果长度:"+digestBytes.length);
  •  SHA---Secure Hash Algorithm

  1. SHA-1---Secure Hash Algorithm 1
  2. SHA-256---Secure Hash Algorithm 256
  3. SHA-512---Secure Hash Algorithm 512

因为这些常见算法的实现操作都基本大差不差,为了方便我们进行快速操作, 所以创建了一个Hashtools类,详细代码如下:

//创建私有类方便操作避免代码冗余
private static MessageDigest digest;
//无参构造方法
private Hashtools() {}
//通过消息摘要对象,处理加密内容
private static String hanler(String source) {
		digest.update(source.getBytes());
		byte[] bytes = digest.digest();
		String hash = BytestoHex(bytes);
		return hash;
	}
//字节数组转换16进制字符串
public static String BytestoHex(byte[] b) {
		StringBuilder builder = new StringBuilder();
		for (byte c : b) {
			//将字节值转换为2位十六进制字符串
			builder.append(String.format("%02x", c));
		}
		return builder.toString();
	}
	
//按照sha-1加密
public static String DigestBySha1(String source) throws NoSuchAlgorithmException {
		digest = MessageDigest.getInstance("sha-1");
		return hanler(source);
	}
//按照sha-256加密
public static String DigestBySha256(String source) throws NoSuchAlgorithmException {
		digest = MessageDigest.getInstance("sha-256");
		return hanler(source);
	}
//按照sha-512加密
public static String DigestBySha512(String source) throws NoSuchAlgorithmException {
		digest = MessageDigest.getInstance("sha-512");
		return hanler(source);
	}
	
//按照md5加密
public static String DigestByMd5(String source) throws NoSuchAlgorithmException {
    	digest = MessageDigest.getInstance("md5");
		return hanler(source);
		
	}

有了这个Hashtools事半功倍,算法实现代码就变得简洁明了。算法输出结果如下:

String str = "edefrev";
String md5 = Hashtools.DigestByMd5(str);
String sha-1 = Hashtools.DigestBySha1(str);
String sha-256 = Hashtools.DigestBySha256(str);
String sha-512 = Hashtools.DigestBySha512(str);
		
System.out.println("md5="+md5);
System.out.println("sha-1="+sha-1);
System.out.println("sha-256="+sha-256);
System.out.println("sha-512="+sha5-12);
  •  RipeMD160算法

      Java标准库提供了一系列常用的哈希算法,但是没有RipeMD160算法,所以为了实现它我们需要找到一个现成的第三方库bouncycastle去使用这个方法。在使用前我们需要去官方网站bouncycastle.org下载我们要使用jar包,然后Build Path>>>add....。

      Java标准库的java.security包提供了一种标准机制,允许第三方提供商无缝接入。我们要使用BouncyCastle提供的RipeMD160算法,需要先把BouncyCastle注册一下:

//注册BouncyCastle BouncyCastleProvider通知类
//将提供的消息摘要算法注册至Security
Security.addProvider(new BouncyCastleProvider());

 然后就可以实现算法啦~

//获取RipeMd160算法的信息摘要对象
MessageDigest digest = MessageDigest.getInstance("ripemd160");
//更新数据
digest.update("dddd".getBytes());
//获取信息加密
byte[] result = digest.digest();
//信息摘要字节长度玉内容
System.out.println("加密结果字节长度"+result.length);
System.out.println("加密结果字节内容"+Arrays.toString(result));
//16进制内容字符串
String hex = new BigInteger(1,result).toString(16);
System.out.println("加密结果字符串长度"+hex.length());
System.out.println("加密结果字符串内容"+hex);

 四、小总结

哈希算法具有以下优点:

  1. 不可逆:无法从摘要中推算出原始数据。

  2. 唯一性:不同的输入会得到不同的摘要。

  3. 敏感性:原始数据的微小变化也会导致摘要的大幅变化。

  4. 固定长度:输出的摘要长度是固定的。

哈希算法也有以下缺点:

  1. 取决于输入长度:输入长度不同,输出长度也不同。

  2. 可能存在碰撞:不同的输入可能会产生相同的摘要。

  3. 不能解密:无法通过摘要找到原始数据。

  如果正确使用本软件可使其加密的文件无法破解。达到安全加密的效果。加密可破解是从业者一直努力的方向,上世纪初曾经也出现过这样的应用,现在是计算机高速发展的时代,实现安全加密更容易了,实践证明用少量密钥(用户密码)去加密大量数据是安全的,要想安全加密至少要为每一个被加密的信息配置一个密钥,这样使得密钥和原文件一样大,造成了密钥保存和分发的困难,该付出的成本必须付出,这里的解决办法是让密钥形成文件,使其安全的和原文件的密文放在一起,做到这一点就是对密钥文件或密文再次进行加密,注意现在密文和密钥文件都是乱码数据,对其加密方法得当是可破解的,因为你知道乱码文件的任何信息你是无法解密的,没有任何评判标准。这样的结果,实现安全加密的代价,1)占用空间大了一倍,2)操作复杂一些。这对于计算机速度越来越快,存储空间越来越便宜的现代应该是没有问题的。   这儿有两个加密程序,每个程序都可独立运行,它们的界面上都有各自的使用说明,都能完成对文件的加密,用户需要熟练的应用它们。这两个程序作用相同,程序 1是以一字一密方式加密文件的,加密后除了生成密文另外还生成一个密钥文件。程序 2是用来给乱码文件加密的,程序2是采用随机置换的加密方式,对乱码数据的加密,即高效又快捷,你需要输入密码,具体用法看各程序在界面上的说明,加密都完成后,密文和乱码文件的密文,可以随便放到什么地方,任何人对这两个文件的攻击都将失败。解密时首先要解密程序2加密的文件,然后再利用密钥文件来解密密文。   程序1加密的文件为什么能破解,道理很简单,程序1为每个原文件的字节生成一个字节的未知数,用这个未知数去加密源文件字节,从而生成一个密文字节,也就是           明密文字节 + 密钥字节 = 密文字节 如此可见一个方程两个未知数,是无解的。要解必须要有密钥字节。   我们看到,密文和密钥文件的密文都是乱码,如果加密密钥文件你需要用安全的地方来保存密钥文件,但是如果有安全的地方保存文件你为何直接保存原文件算了,何必多此一举,而加密后你只要记住密码就可以了。加密后的密钥文件是否安全?如果文件是乱码加密得当是无法破解的,如果用winrar和其它能报告你密码错误的加密软件是安全的,本质上那类软件是出卖自己的。我们需要检测结果正误的加密软件,这样才能做到为窃密者提供信息,才能确保信息安全。破解者因为知道任何评判标准而无法实施解密。   这里有三种选择,1)用程序2 加密密钥文件。2) 用程序2 加密密文。3)用程序2 加密密钥文件和密文。都是可以的,但用户必须自己清楚,解密时需按原路返回差一点都行的。 【使用者须知】   基本功——首先找一些文件,用程序1和程序2分别进行加密解密试验,从单文件开始,到同时处理几个文件,练习到准确无误。   然后就可以练习下面的内容了:   练习一加密部分   用程序1加密文件A,得到A密文和A密钥文件(密钥文件的特征是扩展名最后是my),然后用程序2加密A的密钥文件,加密结束。注意对文件加密时,文件的名称并未改变,操作者自己要记清楚。   练习一解密部分    操作顺序一定要清楚,最后加密的要最先解密,首先用程序2解密加密的密钥文件,然后用程序1解密密文。   上述练习一是三种加密方式的第一种,读者可以尝试另外两种方式。   程序1是必可少的,因为这有此种方法理论上是可破解的这是其它软件做到的,你可以用程序2来加密密钥文件,而用随便一种性能错,又检测解密正误的程序来加密密钥文件等,同样可以安全加密。 如何挑选第三方软件   1)如果用此软件加密一个10M以上的单字符大文件,形成的密文能通过NIST检测,说明此软件性能错。   2)解密时,如果密码输入错误,报告错误。这个一试便知。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

猿究院懒羊羊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值