单向散列函数 (Hash)

1. 单向散列函数

单向散列函数 ------- 获取消息的指纹

在刑事侦查中,侦查员会用到指纹。通过将犯罪现场采集的指纹与指纹库比对,或与嫌疑人的指纹进行比对,就能够知道谁与案件有关联

在计算机中,有时候也会用到"指纹"。当需要比较两条消息是否一致时,通常不必对消息内容比较,直接比较它们的"指纹"就行。

1.1 什么是单向散列函数

单向散列函数,有一个输入和一个输出,其中输入称为消息(message),输出称为散列值(hash value)。单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检查消息的完整性。 简单说就是把任意长度的内容转换成固定长度的输出串,且通过输出串难以还原 原始内容

单向散列函数

这里的消息不一定是人能看懂的文字,可以是图片或者声音文件。单向散列函数不需要知道消息实际代表的含义。无论任何消息,单向散列函数都会将它作为单纯的比特序列来处理。即根据比特序列计算出散列值

散列值的长度和消息的长度无关。无论消息多大,单向散列函数都会计算出固定长度的散列值。以sha-1单向散列函数为例,它计算出的散列值的长度永远都是160比特(20字节)。

1.2 术语

单向散列函数相关的术语,有很多变体,不同参考资料中所使用的术语也不同。
单向散列函数也被称为消息摘要函数(message digest function) 、哈希函数或者杂凑函数
输入单向散列函数的消息也成为原像(pre-image)。
单向散列函数的输出值也称为消息摘要(message digest)护或者指纹(fingerprint)。
完整性也成为一致性。

1.3 单向散列函数的特性

通过使用单向散列函数,即便是确认几百MB大小的文件完整性,也只要对比很小的散列值就可以了。通常将单向散列函数拥有以下特性。

  1. 根据任意长度的消息计算出固定长度的散列值

首先,单向散列值的输入必须能够是任意长度的消息。
无论输入多长的消息,单向散列函数必须能够生成很短的散列值。

  1. 能够快速计算出散列值

计算散列值所花费的时间必须要短。

  1. 消息不同散列值也不同

为了能够确认完整性,消息中哪怕只有1比特的改变,也必须有很高概率产生不同的散列值。
两个不同的消息产生同一个散列值的情况被称为碰撞(collsion)。

碰撞性
难以发生碰撞的性质称为抗碰撞性。密码技术中所使用的单向散列函数,都要具备抗碰撞性。
碰撞性

  1. 具备单向性

单向散列函数必须具备单向性(one-way)。 单向性指的是无法通过散列值反算出消息的性质。根据消息计算出散列值可以很容易,但计算路径无法反推。

单向性
正如同将玻璃粉碎很容易,却无法将碎片还原成原先的玻璃。估计消息计算出散列值很容易,但根据散列值却无法逆推算出消息。

单向散列函数并不是一种加密,因此无法通过解密将散列值还原为原阿里的消息。

1.4 单向散列函数的实际应用

1.4.1 检测软件是否被篡改

可以使用单向散列函数来确认自己下载的软件是否被篡改。

很多软件,都会把散列值公布在官方网站上。用户下载完软件后可自行计算散列值,与官方的散列值进行比对。来确认自己下载的软件是否与提供者的一致。

为了减轻服务器压力,很多软件都会借助多个网站(镜像站点)发布软件,在这种情况下,单向散列函数就会在检测软件是否被篡改方法发挥重要作用。
软件是否篡改

1.4.2 消息认证码

使用单向散列函数可以构造消息认证码

消息认证码是将"发送者和接收者之间的共享密钥"和"消息",进行混合计算后得到的散列值。使用消息认证码可以检测并防止通信过程中的错误,篡改以及伪装。

消息认证码在SSL/TLS中也有使用

1.4.3 数字签名

在进行数字签名时会使用单向散列函数。
数字签名是现实社会中的签名(sign)和盖章这样的行为在电脑世界的实现。数字签名的过程非常耗时,因此一般不会对整个消息内容直接施加数字签名,而是先通过单向散列函数计算出消息的散列值,然后在对这个散列值施加数字签名。

1.4.4 伪随机生成器

使用单向散列函数可以构造伪随机数生成器。

密码技术中所使用的随机数需要具备"事实上不可能根据过去的随机数列预测未来的随机数列"这样的性质。为了保证不可预测性,可以利用单向散列函数的单向性。

1.4.5 一次性口令

使用单向散列函数可以构造一次性口令(one-time password)

一次性口令经常被用于服务器对客户端的合法性认证。在这种方式中,通过使用单向散列函数可以保证口令在通信链路上传送一次(one-time),因此即使窃听者窃取了口令,也无法使用。

1.5 常用的单向散列函数

MD4 MD5 SHA1 SHA-224 SHA-256 SHA-384 SHA-512

算法比特数字节数
MD4128bit16byte
MD5128bit16byte
SHA-1160bit20byte
SHA-224224bit28byte
SHA-256256bit32byte
SHA-384384bit48byte
SHA-512512bit64byte
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是Python实现SHA-1算法的程序,包含了对消息的填充分组、消息扩展、循环移位、与(或、非)运算、模2^32加运算的实现。程序中包含了注释来解释每个步骤的作用。 ```python import struct # 定义SHA-1算法中使用的常量 h0 = 0x67452301 h1 = 0xEFCDAB89 h2 = 0x98BADCFE h3 = 0x10325476 h4 = 0xC3D2E1F0 # 定义SHA-1算法中使用的函数 def sha1(message): # 将消息填充为512位的分组 padded_message = pad_message(message) # 将每个分组的16个32比特字扩展为80个32比特字 for i in range(0, len(padded_message), 64): block = padded_message[i:i+64] words = [0] * 80 for j in range(16): words[j] = struct.unpack('>I', block[j*4:j*4+4])[0] for j in range(16, 80): words[j] = left_rotate(words[j-3] ^ words[j-8] ^ words[j-14] ^ words[j-16], 1) # 初始化单向散列函数的值 a, b, c, d, e = h0, h1, h2, h3, h4 # 迭代修改单向散列函数的值 for j in range(80): if j < 20: f = (b & c) | ((~b) & d) k = 0x5A827999 elif j < 40: f = b ^ c ^ d k = 0x6ED9EBA1 elif j < 60: f = (b & c) | (b & d) | (c & d) k = 0x8F1BBCDC else: f = b ^ c ^ d k = 0xCA62C1D6 temp = (left_rotate(a, 5) + f + e + k + words[j]) & 0xFFFFFFFF e = d d = c c = left_rotate(b, 30) b = a a = temp # 将迭代修改后的值与初始的单向散列函数值相加 h0 = (h0 + a) & 0xFFFFFFFF h1 = (h1 + b) & 0xFFFFFFFF h2 = (h2 + c) & 0xFFFFFFFF h3 = (h3 + d) & 0xFFFFFFFF h4 = (h4 + e) & 0xFFFFFFFF # 输出最后的单向散列函数值 return '%08x%08x%08x%08x%08x' % (h0, h1, h2, h3, h4) # 将消息填充为512位的分组 def pad_message(message): # 计算消息的比特长度 message_length = len(message) * 8 # 添加比特'1',直到消息长度为448模512 message += b'\x80' while (len(message) * 8) % 512 != 448: message += b'\x00' # 添加消息长度的64位比特表示 message += struct.pack('>Q', message_length) return message # 将32比特的值循环左移n位 def left_rotate(n, b): return ((n << b) | (n >> (32 - b))) & 0xFFFFFFFF # 32比特与(或、非)运算 def ch(x, y, z): return (x & y) ^ (~x & z) # 32比特与(或、非)运算 def maj(x, y, z): return (x & y) ^ (x & z) ^ (y & z) # 模2^32加运算 def sum32(x, y): return (x + y) & 0xFFFFFFFF ``` 下面是一个演示SHA-1算法计算过程的示例程序,它将输入的消息作为参数传递给SHA-1算法函数,并输出最终的单向散列函数值。 ```python message = b'This is a test message' hash_value = sha1(message) print('SHA-1 hash of', message, 'is', hash_value) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值