2.4 哈希函数Hash
2.4.1 消息摘要
我们通过上节内容知道,数字签名就是用自己的私钥对文件M进行加密,而这个文件M通常来说会很大,使用非对称加密算法直接对文件M进行签名是非常慢的,因此不妨先对文件M进行压缩,并且希望这个“压缩”满足以下两个条件:
(1)结果可以“唯一”代表M;
(2)具有固定长度。
这个“压缩”通常被称为M的消息摘要,又称单向加密,意即能通过“加密”但不能通过解密来恢复原文。
能生成M的消息摘要的函数被称为单向哈希函数,也被称为哈希函数、Hash函数、杂凑函数或哈希函数。
构造哈希函数非常不容易。我国制定的哈希函数Hash标准为SM3。
2.4.2 数字指纹
我们通过上节内容知道,M被篡改后得到的消息摘要会不同,即消息摘要是消息的权威代表,可视为消息的指纹,称为数字指纹,用h表示。
一旦篡改了M则算出的数字指纹h也会变化,即通过数字指纹是否变化来判断原文是否被篡改,这就是防篡改的原理。
“请签名并按手印”是我们日常签署文件的场景,我们先在文件上签名,再按手印得到指纹。签名表示认可该文件,按手印表示签名是真实的。
而这里的情况完全不同,从次序看完全相反,对一个大文件先求出它的数字指纹,数字指纹是文件M的指纹,表示对文件的压缩和防篡改,再对指纹签名,表示对文件的确认,数字签名不能被模仿。
2.4.3 数据块的指针
如图2.3所示,数据A通过哈希算法产生了一串数字为数据A的数字指纹a。反过来,数字指纹a能“索引”到数据A,即指针,但不是空间定位索引。
图2.3 数据和指纹
数据A对应的数字指针a具有双重意义:一是作为指纹,二是作为指针。由于是用哈希算法产生的,因此这类“指针”被称为哈希指针,如图2.4所示。
图2.4 哈希指针
显然,哈希指针并不能直接实现“定位”,就像通过犯罪嫌疑人的指纹并不能直接得到犯罪嫌疑人的门牌号码一样,并不是有些作者通常认为的“哈希指针指向数据的存储位置”。这个错误会误导大家。这是因为:
其一,是先有已存储在内存中的数据A,再有哈希指针,没有必要在算出哈希指针后,将数据移到指针指示的位置;
其二,哈希指针值是很大的,一般为256位,远大于目前的64位寻址空间;
其三,即使有足够大的空间,那么移动数据到哈希指针所指示的位置,会不会与附近的数据块部分重叠?在C语言中,是先向系统申请分配内存用于存放数据,再将该内存的地址赋给指针的。
哈希指针可借助某种辅助手段实现某种定位,例如,将(a,A)视为(Key,Value),以数据库的方式即可实现快速定位,说明数字指纹a确实可以看成是“指针”,只不过它不是通常意义下的地址指针。
2.4.4 基于Hash的数字签名
我们知道,交易必须要防伪造和防抵赖,这在日常商务活动中靠签名和盖章来保证,在无纸化环境中使用密码或数字签名来保证。显然,数字签名优于密码,因为数字签名可以实现同交易的“绑定”,即同一个人、不同的交易产生的数字签名不同。
数字签名的机制与作用与手写签名类似:
(1)我能方便地进行签名——用我的私钥进行数字签名;
(2)别人能方便地验证是不是我的签名——用我的公钥对我的签名进行验证,能通过即是我的签名,否则为仿冒;
(3)签名与特定的内容绑定,即不能篡改内容——内容参与签名的运算,即签名过程的输入是内容和私钥;
(4)签名要考虑效率,显然,手工对多页合同的每页都签名的效率不如先将内容压缩到一页再签名——我们知道Hash函数有压缩功能,可以对压缩结果,即消息摘要进行签名。这虽不是必需的,但很重要,因为,签名算法本身在时间上的花费与签名内容的长度成正比。数字签名通常就是指对数据的消息摘要即Hash值进行的数字签名。
数字签名,即电子签名的一个典型例子是证书,即公钥证书。它是对数字签名的申明,将公钥与特定使用者(如个人、设备或服务)进行绑定,向使用者提供公钥,用于加密等。重要网站通常会将自身证书颁发给客户端下载、安装或自动下载。例如,你运行命令行certmgr.msc,就可以看到自己计算机中的证书列表,打开其中一个证书,就可以在“详细信息”中看到颁发者、有效期、公钥、指纹、各种算法等。