信息摘要
- 区别于对称加密和非对称加密,信息摘要算数是一种不可逆的操作,无论输入数据的大小输出的数据长度是固定的
- 信息摘要算数对输入很敏感,即使数据变化很细微,输出的结果会出现很大的差异
- 从不同输入得到相同的输出的概率非常低,因此信息摘要算数用于验证数据的完整性
数字签名算法
- 非对称加密算法,实质是使用非对称算法的私钥对数据进行加密,使用公钥对密文进行验证
- 数字签名算法配合信息摘要算法的整体流程
- OpenSSL目前支持的信息摘要算法包括SHA1、SHA、MD5、MD4、MD2、MDC2和RIPEMD160。OpenSSL对所有这些信息摘要算法都提供了单独的同名指令,此外,还使用了统一的指令dgst集成了所有支持的信息摘要算法的操作。
- 因为信息摘要算法通常跟数字签名一起使用,所以,在所有的信息摘要算法指令中,OpenSSL还支持使用RSA或者DSA密钥对摘要信息进行数字签名和验证过程,也就是说,所有这些信息摘要指令都能够完成上面介绍的数字签名的流程和数字签名验证的流程,这对于实际的应用具有重大的意义。
- 如表所示 列出了OpenSSL支持的信息摘要指令。
- dgst指令的格式和其他信息摘要算法指令的格式基本上是保持一致的,下面是使用sha1算法进行信息摘要操作的两个指令:
- 如果你执行了上述两条指令,会发现它们的输出结果是一样的,因为它们采用了相同的信息摘要算法SHA1。
- 仔细比较还会发现,这两个指令除了dgst多了一个选择算法的选项外,其他选项也是一致的。
- dgst指令跟其他单独的信息摘要指令的不同之处还在于它支持使用DSA密钥进行数字签名和验证操作。因为dgst和其他各种信息摘要算法的指令格式基本一致,所以在本章的介绍中,将以dgst指令为主线,在必要的时候给出其他信息摘要算法指令的说明。
dgst指令格式
-
其他信息摘要算法指令通用的格式
- 上述指令中,dgst_cipher是OpenSSL支持的各种信息摘要算法的名称,跟dgst指令中的dgst_cipher选项是基本一致的,但是在单独指令中,不支持dss1指令的操作。我们如果要使用MD5信息摘要算法对一个文件进行信息摘要操作,则下面两个指令是等价的:
- 算法类型参数字段的数值不区分大小写,sha等同于SHA
- 从表还可以看出,摘要信息的位数一般都远远小于我们常用的公开密钥算法的密钥位数(1024),所以对摘要信息的签名可以一次完成,与直接对原始文件签名相比大大提高了签名速度和验证速度。
指令选项说明
信息摘要算法选项
- 对于dgst指令来说,可采用的信息摘要算法有8种,具体参数可以参考表。对于单独的信息摘要算法来说,该选项是不存在的,因为其指令本身就已经限定了使用的信息摘要算法
输出文件选项out
- 输出文件选项out指定了输出信息的文件,输出的信息包括摘要信息、验证成功与否的信息及数字签名信息等。输出信息的格式根据使用的输出格式选项的不一样而不同。默认情况下使用的输出文件是标准输出设备,一般是当前指令行界面。
输入文件选项files
- 该选项一般放在各个选项的最后,直接输入要进行信息摘要操作、数字签名操作或者验证签名操作的文件即可。dgst指令和其他单独的信息摘要指令在这里可以同时对多个文件进行信息摘要操作,但是对于数字签名和签名验证操作则只能每次针对一个文件,否则就可能导致验证失败。需要注意的是,无论是进行信息摘要操作、数字签名操作还是验证签名操作,这里输入的都应该是原来的明文文件。在信息摘要操作和数字签名操作中,该文件信息被用来作为信息摘要函数的输入,得到的摘要信息被保存或者进一步经过私钥签名后保存;而在签名验证过程中,该文件信息也被作为信息摘要函数的输入,其结果跟用公钥解密的数字签名信息进行对比,如果一致,则验证通过,否则验证就失败。
数字签名选项
- dgst指令和其他单独的信息摘要指令仅提供了一个跟签名有关的选项sign,该选项的参数存储了一个RSA或者DSA私钥的文件。如果是RSA私钥,那么说明将要使用的数字签名算法是RSA算法,如果使用的是DSA私钥,那么说明将要使用的算法是DSA数字签名算法。DSA数字签名算法只能在dgst指令中使用,并且要同时使用ds1作为算法选项参数。输入私钥的编码格式由keyform选项指定,其格式可以是多种多样的。
数字签名验证选项
- dgst指令和其他单独信息摘要指令提供了三个跟数字签名验证有关的选项signature、verify和prverify。signatrue指定了保存要进行验证的签名信息的文件,通常来说,为了正确验证,应该是一个二进制编码的文件,十六进制编码的文件可能导致不能正确验证。这需要在进行数字签名的时候不使用hex选项。
- verify选项跟prverify选项不能同时使用。使用verify选项表示将要输入的用于验证数字签名的密钥是一个公钥;如果使用prverify选项,则表示将要输入的文件保存的是一个私钥,指令将从这个私钥中读取其公钥参数进行数字签名的验证,之所以能够这么做,是因为私钥结构里面通常保存了所用公钥参数。输入密钥的编码格式由keyform选项决定。
输入密钥格式选项keyform
- keyform选项告诉指令输入用于签名或者验证的密钥属于什么编码格式。目前来说,如果输入的是私钥(使用sign选项签名或者prverify选项验证的时候),支持的格式包括DER编码格式、PEM编码格式、PKCS#12编码格式、Netscape编码格式、旧版的ISSGC编码格式及ENGINE密钥格式。如果输入的是公钥(使用verify选项验证的时候),则比私钥少支持一种PKCS#12格式,这是因为PKCS#12格式一般用来封装证书和私钥,而不直接用于封装公钥。如果keyform指定的密钥格式是ENGINE格式(-keyforme),那么输入的密钥文件的内容和意义需要根据具体Engine接口而定,可能只是一个特定的字符串ID,可能是一个公钥,也可能是毫无用处的内容。
engine选项
- engine选项指定了替代OpenSSL默认算法库的Engine设备。对dgst指令和其他信息摘要算法指令来说,使用Engine选项可能会对几个方面产生影响。首先是信息摘要算法,如果指定的Engine接口有效并且支持该选定的信息摘要算法,那么Engine设备里面的信息摘要算法就会被启用。其次是数字签名和验证算法,如果指定Engine设备有效并且支持使用的数字签名和验证算法,那么Engine设备的数字签名和验证算法就会被启用。第三个是随机数产生及相关的操作,如果Engine设备支持随机数产生和其他相关操作,那么这些Engine操作也会被启用以替代OpenSSL本身的函数。
输出格式选项
- 为了看起来方便或者其他原因,可能需要对输出的摘要信息和数字签名信息做一些格式调整,比如将二进制格式转换成十六进制等。OpenSSL提供了一些此类选项。hex选项可以将输出的摘要信息或者签名信息进行十六进制编码后输出,但是验证的时候可能导致验证失败。c选项只有跟hex选项一起使用才有效,它在每个十六进制数据编码之间增加一个分隔符“:”,这样便于查看。默认的摘要信息和签名信息是以二进制的形式输出的,如果要显式表示使用二进制输出,可以使用binary选项。d选项使用后指令会将BIO读取文件的操作信息打印出来,一般是为了调试的目的才会使用这个选项。
随机数文件选项
- 在dgst或其他信息摘要指令操作的过程中,有时候需要用到随机数,那么同样需要一个随机数种子文件,这可以通过rand选项指定。事实上,在所有指令的rand选项中,指定的随机数文件可以不止一个,而可以是多个,文件之间根据应用系统的不同采用不同的符号进行连接。比如Windows系统可以使用“;”作为连接符号,OpenVMS系统采用“,”作为连接符号,而其他系统则采用“:”作为连接符号。例如下面是Windows系统中使用多个随机数文件的形式:
- 如果不使用rand选项,指令会从其他可用资源获取随机数种子。
使用信息摘要指令进行数字签名和验证
- 执行数字签名
有个问题,通过私钥推导公钥的时候并不知道 对私钥加密使用的对称加密算法的种类是啥,仅仅输入了对称密钥是如何解密的呢??
验证数字签名