数字安全一之消息摘要

一、消息摘要的定义

消息摘要(Message Digest)是加密术语中一种通过散列函数生成的【固定长度的字符串】。它是对任意长度的输入消息(如文件、字符串等)进行处理后产生的【固定长度的唯一标识符】

二、消息摘要的作用

完整性校验:通过生成消息的摘要值,可以在接收方对收到的消息进行相同的摘要计算,若摘要值相同,说明消息未被篡改;若摘要值不同,则表明消息可能被修改。

数字签名:消息摘要是数字签名算法的重要组成部分。发送方可以通过对消息摘要进行加密,生成数字签名,接收方则可以通过解密并对消息进行摘要比对,确保消息的真实性和完整性。

快速比较:由于消息摘要是固定长度且唯一的标识符,可以用它快速比较两条消息是否相同,而不需要逐字节比较消息内容。

常见的消息摘要算法有 MD5、SHA-1、SHA-256 等。尽管 MD5 和 SHA-1 已不再安全,SHA-256 及其他更高级的算法仍然被广泛使用。

三、摘要算法
3.1、SHA-256 (安全散列算法)

SHA名称来自于安全散列算法(英语:Secure Hash Algorithm)的缩写,一种密码散列函数算法标准,由美国国家安全局研发(NSA)。

它们的【摘要长度】(以比特计算)加在原名后面来命名:SHA-256,SHA-384和SHA-512。

SHA-256固定长度输出:无论输入的大小,输出总是 256 位(32 字节)

3.2、MD5 (信息摘要算法)

MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。

3.3、SHA-256和md5比较

特性

SHA-256

MD5

哈希输出长度

256 位(32 字节)

128 位(16 字节)

安全性

非常安全,适合密码学应用

不安全,已被淘汰

抗碰撞能力

极强,尚无实用碰撞攻击

已被破解,容易找到碰撞

应用场景

密码学、区块链、数字签名等

文件校验等非安全场景

速度

较慢,运算复杂

较快,运算轻量

设计者

美国国家安全局 (NSA)

Ronald Rivest

发布日期

2001

1991

3.4、代码实现
3.4.1 sha-256
    // SHA-256 java版本实现
	import java.security.MessageDigest;
	public class SHA256Example {
		public static void main(String[] args) throws Exception {
			String input = "hello";
			
			// 获取 SHA-256 实例
			MessageDigest digest = MessageDigest.getInstance("SHA-256");
			
			// 计算哈希值
			byte[] hash = digest.digest(input.getBytes("UTF-8"));
			
			// 将字节数组转为十六进制字符串
			StringBuilder hexString = new StringBuilder();
			for (byte b : hash) {
				String hex = Integer.toHexString(0xff & b);
				if (hex.length() == 1) hexString.append('0');
				hexString.append(hex);
			}
			
			System.out.println(hexString.toString());  // 输出64个字符的十六进制字符串
		}
	}
3.4.2、md5
	import java.security.NoSuchAlgorithmException;
	public class MD5Example {
    public static void main(String[] args) {
        String input = "Hello, World!";
        
        try {
            // 创建 MD5 算法的 MessageDigest 实例
            MessageDigest md = MessageDigest.getInstance("MD5");
            
            // 将输入字符串转换为字节数组并更新到摘要中
            byte[] messageDigest = md.digest(input.getBytes("UTF-8"));
            
            // 将字节数组转换为十六进制格式的字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0'); // 补零确保每个字节是两位数
                }
                hexString.append(hex);
            }
            
            // 输出 MD5 哈希值
            System.out.println("MD5 Hash of '" + input + "': " + hexString.toString());
            
        } catch (NoSuchAlgorithmException e) {
            // 捕获当系统不支持 MD5 算法时的异常
            System.err.println("MD5 Algorithm not found.");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}
3.5、SHA-256输出长度为256位(32字节)转64长度的字符串

这是因为该输出使用了 十六进制(Hex)编码 表示。
1.SHA-256 输出的本质:SHA-256 的散列值是一个 256 位 的二进制数字,即 32 字节(每个字节 8 位)。
2.十六进制编码:为了更容易查看和传输,通常将二进制数据用十六进制表示。十六进制用 16 个字符来表示二进制(每个字符 4 位),因此每个字节(8 位)可以用 2 个十六进制字符表示。
3.长度计算:如果 SHA-256 的输出是 32 字节(256 位),使用十六进制编码时,每个字节需要 2 个十六进制字符来表示,因此最终的输出长度为64个字符的字符串
4.(每个字符 4 位):每个字符 4 位的概念是指在 十六进制(Hexadecimal)编码中,一个十六进制字符可以表示 4 位二进制数字。这是因为十六进制是一种基数为 16 的数制,范围从 0 到 F,而这些字符可以直接映射到二进制的 4 位表示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值