目录
-
-
- [Python 实现 SHA-1 数字摘要签名算法的博客](#Python 实现 SHA-1 数字摘要签名算法的博客)
-
- 引言
- [SHA-1 算法介绍](#SHA-1 算法介绍)
- [SHA-1 算法的详细步骤](#SHA-1 算法的详细步骤)
- [Python 面向对象实现 SHA-1 算法](#Python 面向对象实现 SHA-1 算法)
- 代码解释
- 场景应用:文件完整性验证
- 示例:文件完整性验证
- 总结
-
Python 实现 SHA-1 数字摘要签名算法的博客
引言
SHA-1(Secure Hash Algorithm 1)是一种安全哈希算法,用于生成一个固定长度的160位(20字节)哈希值。虽然SHA-1在密码学中的安全性已被削弱,不再建议用于数字签名等安全应用,但它仍然在某些非安全场景中使用。SHA-1的设计基于MD4和MD5算法,并被广泛用于数据完整性验证和哈希表等领域。
本文将详细介绍SHA-1算法的工作原理,提供一个基于Python面向对象的实现,并结合一个实际场景来演示如何使用SHA-1算法。
SHA-1 算法介绍
SHA-1 是一种基于块的哈希算法,它对输入的消息进行处理,输出固定长度的160位哈希值。SHA-1的工作原理与其他哈希算法类似,通过对输入数据进行多次非线性和不可逆的操作,生成唯一的摘要。
SHA-1 的主要步骤包括:
- 消息填充(Padding):将消息的长度扩展到接近512的倍数,最后64位表示原始消息的长度。
- 初始化哈希值:使用5个32位寄存器(A, B, C, D, E)来存储中间和最终的哈希值。
- 处理消息块:将消息块划分为512位的块,每块处理80轮,使用5个逻辑函数和固定常量来进行哈希计算。
- 输出哈希值:最后输出一个160位的哈希值。
SHA-1 算法的详细步骤
-
消息填充:
- 首先在消息的末尾添加一个
1
位,接着添加足够的0
位,使其长度模512为448。 - 然后在末尾附加一个64位的二进制数,表示填充前的消息长度。
- 首先在消息的末尾添加一个
-
初始化哈希值:
- SHA-1 使用五个32位的初始哈希值:
A = 0x67452301
B = 0xEFCDAB89
C = 0x98BADCFE
D = 0x10325476
E = 0xC3D2E1F0
- SHA-1 使用五个32位的初始哈希值:
-
处理每个消息块:
- 消息被分为512位的块,每个块再划分为16个32位的字(word)。
- 然后扩展为80个字,每个字是前四个字的异或操作。
- 对于每个字,SHA-1进行80轮的哈希运算,使用5个逻辑函数
F(t)
和5个常量K(t)
。
-
逻辑函数:
- 不同的逻辑函数用于每20轮的操作:
F(t) = (B AND C) OR ((NOT B) AND D)
, 0 ≤ t ≤ 19F(t) = B XOR C XOR D
, 20 ≤ t ≤ 39F(t) = (B AND C) OR (B AND D) OR (C AND D)
, 40 ≤ t ≤ 59F(t) = B XOR C XOR D
, 60 ≤ t ≤ 79
- 不同的逻辑函数用于每20轮的操作:
-
常量
K(t)
:- 每20轮的操作使用一个不同的常量:
K(0 ≤ t ≤ 19) = 0x5A827999
K(20 ≤ t ≤ 39) = 0x6ED9EBA1
K(40 ≤ t ≤ 59) = 0x8F1BBCDC
K(60 ≤ t ≤ 79) = 0xCA62C1D6
- 每20轮的操作使用一个不同的常量:
-
输出最终哈希值:
- 将每个块的计算结果累加到初始哈希值中,最后输出160位的哈希值。
Python 面向对象实现 SHA-1 算法
以下是一个基于Python面向对象的SHA-1实现,用于计算输入字符串的SHA-1哈希值。
python
import struct
class SHA1:
def __init__(self, message):
"""
初始化SHA1实例
"""
self.message = message
self.h = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]
self._hash = self._calculate_sha1()
def _left_rotate(self, n, b):
"""
执行左循环位移操作
"""
return ((n << b) | (n >> (32 - b))) & 0xFFFFFFFF
def _padding(self):
"""
对消息进行填充,使其长度为512的倍数
"""
original_byte_len = len(self.message)
original_bit_len = original_byte_len * 8
# 对消息填充一个'1'位
self.message += b'\x80'
# 填充'0'直到消息长度模512等于448位(56字节)
self.message += b'\x00' * ((56 - (original_byte_len + 1) % 64) % 64)
# 在最后添加64位的原始消息长度
self.message += struct.pack('>Q', original_bit_len)
def _calculate_sha1(self):
"""
计算SHA-1哈希值的主方法
"""
self.message = bytearray(self.message, 'utf-8')
self._padding()
# 每512位一个分组进行处理
for i in range(0, len(self.message), 64):
w = list(struct.unpack('>16L', self.message[i:i + 64])) + [0] * 64
for j in range(16, 80):
w[j] = self._left_rotate(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1)
a, b, c, d, e = self.h
# 80轮操作
for j in range(80):
if 0 <= j <= 19:
f = (b & c) | ((~b) & d)
k = 0x5A827999
elif 20 <= j <= 39:
f = b ^ c ^ d
k = 0x6ED9EBA1
elif 40 <= j <= 59:
f = (b & c) | (b & d) | (c & d)
k = 0x8F1BBCDC
else:
f = b ^ c ^ d
k = 0xCA62C1D6
temp = (self._left_rotate(a, 5) + f + e + k + w[j]) & 0xFFFFFFFF
e = d
d = c
c = self._left_rotate(b, 30)
b = a
a = temp
# 更新初始哈希值
self.h[0] = (self.h[0] + a) & 0xFFFFFFFF
self.h[1] = (self.h[1] + b) & 0xFFFFFFFF
self.h[2] = (self.h[2] + c) & 0xFFFFFFFF
self.h[3] = (self.h[3] + d) & 0xFFFFFFFF
self.h[4] = (self.h[4] + e) & 0xFFFFFFFF
return ''.join(f'{value:08x}' for value in self.h)
def hexdigest(self):
"""
返回计算出来的SHA-1哈希值
"""
return self._hash
# 使用SHA1算法计算哈希值
message = "Hello, SHA-1!"
sha1_instance = SHA1(message)
print(f"原始消息: {message}")
print(f"SHA-1哈希值: {sha1_instance.hexdigest()}")
代码解释
- SHA1类:该类实现了SHA-1算法的所有计算步骤和常量。
_padding()
方法:对消息进行填充操作,使其满足SHA-1算法的要求。_calculate_sha1()
方法:实现了SHA-1算法的主步骤,包含消息扩展和80轮哈希计算。hexdigest()
方法:返回计算出来的SHA-1哈希值。
场景应用:文件完整性验证
SHA-1常用于验证文件的完整性。假设你从网络上下载了一个文件,你可以使用SHA-1来计算文件的哈希值,并与文件发布者提供的SHA-1哈希值进行比较,验证文件是否被篡改。
示例:文件完整性验证
python
import hashlib
class FileIntegrityChecker:
def
__init__(self, file_path):
self.file_path = file_path
def compute_sha1(self):
sha1 = hashlib.sha1()
with open(self.file_path, "rb") as f:
while chunk := f.read(4096):
sha1.update(chunk)
return sha1.hexdigest()
def verify(self, expected_sha1):
calculated_sha1 = self.compute_sha1()
print(f"计算得到的SHA-1哈希值: {calculated_sha1}")
return calculated_sha1 == expected_sha1
# 示例用法
file_path = "example.txt" # 替换为你的文件路径
checker = FileIntegrityChecker(file_path)
expected_sha1 = "expected_sha1_hash" # 替换为预期的SHA-1值
if checker.verify(expected_sha1):
print("文件完整性验证通过!")
else:
print("文件可能被篡改!")
总结
本文详细介绍了SHA-1哈希算法的原理、Python实现及其在文件完整性验证中的应用。尽管SHA-1已不再被推荐用于安全场景,但在非安全应用中它仍然是一个有效的工具。理解和实现SHA-1算法,有助于加深对哈希算法的理解及其在信息安全中的作用。