第6章 验证数据完整性—消息摘要算法

相信读者对于MySQL已经非常了解了,作为一款开源的数据库,它已经成为无数开源爱好者的数据库首选。

读者朋友一定对图6-1并不陌生,它是MySQL官方提供的数据库发行版(版本5.1.38)的下载页面(详见http://dev.mysql.com/downloads/mysql/5.1.html#win32)。

figure_0168_0037

图 6-1 MySQL下载页面

在这个下载页面中,有一个不规律的字符串(MD5:5a077abefee447cbb271e2aa7f6d5a47)引起了作者的注意。这个不规律的字符串长度为32个字符,由英文字母和数字组成,很显然这是一个十六进制编码字符串。它还有一个时髦的名字,叫“数字指纹”。它就是本章的主角,消息摘要算法—MD5。

我们看到Windows Essentials(x86)、Windows MSI Installer(x86)和Without installer(unzip in C:\)三种发行版的大小是有所不同的,三种发行版对应的大小分别为38.3MB、103.5MB和126.8MB。但是,其数字指纹的长度却都是一样的,都是32个字符的十六进制串。

6.1 消息摘要算法简述

消息摘要算法包含MD、SHA和MAC共3大系列,常用于验证数据的完整性,是数字签名算法的核心算法。

6.1.1 消息摘要算法的由来

相信读者朋友都有从网上下载软件的经历,偶尔也有从网上下载到破损文件的经历。情况严重时,还可能从某软件的官网上下载到被篡改的软件。如何来验证下载到的文件和官方提供的文件是否一致?这就引入了数据完整性验证的问题。

该如何验证其一致性?肉眼比较?大小比较?均无可取之处!我们需要一种方便快捷、安全有效的算法。

先不说如何比较文件是否相同的问题,我们说说如何比较两个对象是否相同。

相信广大读者朋友都有使用equals()方法来比较对象的经历。但很多读者朋友不知道,实际上equals()方法比较的是两个对象的散列值,即比较两个对象hashCode()方法的值是否相同,这说明hashCode可以作为辨别对象的唯一标识。

什么是hashCode呢?顾名思义,hashCode就是散列值。

我们在第2章中曾经介绍过散列函数,它恰恰能够用于数据完整性的校验。任何消息经过散列函数处理后,都会获得唯一的散列值。这一过程称为“消息摘要”,其散列值称为“数字指纹”,自然其算法就是“消息摘要算法”了。换句话说,如果其数字指纹唯一,就说明其消息是一致的。

由此,消息摘要算法成了校验数据完整性的主要手段。各大软件厂商提供软件下载的同时总要附带上数字签名,这一做法也就不足为奇了。为了能够更加方便、有效地验证数据的完整性,有的软件厂商还提供了不同的消息摘要算法的数字指纹,如MD5和SHA算法,甚至是HMAC算法的数字指纹。此外,用于校验数据完整性的算法还有CRC32算法等。为了方便人们识别和阅读,数字指纹常以十六进制字符串的形式出现。

消息摘要算法最初是用来构建数字签名的。数字签名操作中,签名操作其实是变相地使用消息摘要算法获得的数字指纹,而验证操作则是验证其数字指纹是否相符。这也是为什么当山东大学王小云教授使用碰撞算法破解了MD5和SHA算法后,使得数字签名在理论上被伪造成为可能。

消息摘要算法一直是非对称加密算法中一项举足轻重的关键性算法。