SHA-1 算法在FPGA上的实现 - 1
背景介绍
散列函数(英语:Hash function)又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值(hash values,hash codes,hash sums,或hashes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。SHA-1 (全称:Secure Hash Algorithm - 1,安全散列算法-1)是一种密码散列函数,是由美国国家安全局设计。SHA-1可以使一个不固定长度的消息生成160位的消息摘要,用于验证消息在传输的过程中没有被攻击或者篡改。2005年,密码分析人员发现了对SHA-1的有效攻击方法,2020年后,针对SHA-1的选择前缀攻击已经证明实际可行,建议尽可能使用SHA-2或者SHA-3取代SHA-1。在这里介绍SHA-1算法是因为其对SHA家族算法有代表性,其余算法与SHA-1差别不大。
应用场景举例
SHA-1作为安全散列算法家族的一员,主要作用是用于验证消息在传递的过程中是否被篡改,是被视作验证码。初学者在学习的过程中,经常会将Hash函数与密文、密钥、加密等概念混淆。需要值得注意的是,Hash算法并不能够加密消息或者掩盖消息的真实样貌,技术人员或者学者使用SHA家族算法,只是为了通过移位、异或、交换寄存器内数值、使用消息参与计算的方式,将不固定长度的消息转化为固定长度的消息摘要,用于验证消息的完整性以及可靠性,确认其在传输的过程中没有被修改。于此同时这个消息的计算过程也是不可逆的,因此可以保证了消息的不泄露。
SHA-1算法,在实际生活中的应用场景如下:
1.密码验证:服务器端存储用户密码加密后的内容,每次密码校验比较的是密文是否相同,确保服务器管理员也无法获取到用户使用的密码。
2.文件的完整性比较:当下载一个文件时,服务器返回的信息中包括这个文件的MD5(或者SHA1),在本地下载完毕将其进行MD5加密,之后比较两个MD5只进行比较,如果一直则说明文件完整不存在丢包现象。
3.文件上传:在上传文件信息的时候,将该文件的MD5同时上传给服务器。服务器中存储了这个文件MD5(或者SHA1),并存储这个MD5只对应的已上传的字节长度,比如未上传为0,已完成为-1,已上传200自己,则值为200。可以用于匹配该文件在服务器中的状态,方便断点再传。只要源文件没有改,就算文件改了名字,换个账户都可以在服务器中找到对应的文件,避免存储多份相同文件,并可以提高二次上传时的速度。
SHA-1的计算流程
以上所示的流程图是SHA-1算法实现的流程图。我把它分为了四部分:
第一部分:哈希初始值的输入;
第二部分:消息块的填充,分块;
第三部分:哈希运算;
第四部分:将最后所得的哈希值与哈希初始值相加,得到最终哈希值。
一.哈希初始值输入 (Initial Value Input):
SHA-1算法的特点之一就是将不固定长度的消息块转化为固定长度的验证码,实现这一特点的过程其实就是将5个哈希初始值通过移位、相加、交换位置的方式得到最终的5个散列值。在这个过程中等待处理的消息将参与哈希值的计算,最后得到所需的哈希值进行验证。
哈希初始值一般为:
Initial variables:
h0 := 0x67452301
h1 := 0xEFCDAB89
h2 := 0x98BADCFE
h3 := 0x10325476
h4 := 0xC3D2E1F0
哈希初始值也可以根据需要自行更改。
二.消息块的填充和分块(Message Padding):
每条输入消息的长度不固定,但每一次输入的消息被分块为512位(16个字)作为一组进行处理。很多情况下,消息长度并不是512的整数倍,这时候就要对原始消息进行补填充。假设消息的长度M为L位。将“ 1”附加到消息末尾,后跟k个零位,其中k是方程的最小非负解L+1 + k” 448mod 512。然后附加用二进制表示形式等于的数字L的64位的消息块。例如,(8位ASCII)消息“ abc”的长度8·3 = 24,用"1"填充消息一位,然后填充448-(24 +1)= 423个零位,然后消息长度,成为512位填充消息。效果如图所示。
整个过程可以详细分解为以下两步:
1.补位
原始消息必须进行补位,以使其长度在对512取模以后的余数是448。也就是说,(补位后的消息长度)%512 = 448。即使长度已经满足对512取模后余数是448,补位也必须要进行。
补位是这样进行的:先补一个1,然后再补0 ,直到长度满足对512取模后余数是448。总而言之,补位是至少补一位,最多补512位。
2.补长度
就是将原始数据的长度补到已经进行了补位操作的消息后面。通常用两个字(64位)来表示原始消息的长度。如果消息长度不大于2^64,那么第一个字就是0。
三. 哈希运算(Hash Function):
SHA-1算法运算从初始值开始到最终所得哈希值,会进行80轮运算。上图所示的是每一轮运算的具体操作。
SHA-1 Function
SHA-1使用一系列逻辑函数进行计算,一共计算80轮,分别为f0,f1,…,f79。每个函数ft,其中 ft <79,举个例子,当对三个32位字x,y和z进行运算,并产生一个32位字作为输出。 ft功能(x,y,z)定义如下:
SHA-1 Processing
SHA-1哈希计算使用先前定义的函数和常量进行计算,(+)指的是模 232。
第1轮到第80轮,每一轮都要按顺序用一个32位的消息参与运算,消息本身有512位,也就是16个字。剩余的轮数,通过特殊的算法,将消息扩展为32*80位。算法如下:
具体每一轮的计算方法,如下图所示:
图中的ROTLn(x)为下图所示:
四. 最终哈希值计算
最终哈希值计算为下图所示:
五个初始值与80轮计算后所得哈希值一同计算,所得的值就是我们需要的散列值。
总结
在SHA-1的FPGA实现(1)中,我介绍了SHA-1的历史和作用,并详细的描述了SHA-1算法的运算过程,在下一篇中,我将开始介绍如何将SHA-1算法在FPGA上实现,以及需要注意的事项。
参考资料
[1] SECURE HASH STANDARD https://csrc.nist.gov/csrc/media/publications/fips/180/2/archive/2002-08-01/documents/fips180-2.pdf