【转载】RSA数字签名与加密、解密间的关系
提及RSA,大家会想到公钥、私钥、加密、解密、数字签名、数字信封。。。
但也许大家和曾经的我一样,对其中的某些理解会存在误区,最近看了下关于RSA的RFC 2313文档,再加上自己的一些测试,终于理清了其中的一些关系,主要包括以下几点:
1、公钥和私钥间的关系;
2、数字签名和私钥加密间的关系;
3、数字签名的验证具体是怎样的过程;
公钥与私钥
一般,我们可以用RSA算法生成一对密钥,公钥发放给外部客户,私钥自己保管;有以下一些应用场景:
【公钥加密、私钥解密】或者【私钥加密、公钥验证】
对于第一种场景,似乎没有什么疑问;但是对于第二种场景,公钥验证时到底是如何验证法个人有个人的说法,我以前一直以为是和数字证书一样(当然这个理解有误,关于数字证书后续也会详述),只能验证不能被解密!但经过我的测试证明:私钥加密是可以用公钥解密的;所以说对于RSA算法,用任何一方密钥加密都可以用另外一个密钥解密;这也从另外一个角度说明,其实公钥和私钥是相对而言的,发放其中一个密钥出去,另外一个自然也就成为私钥了;对于该观点,很多同学都已经提到过,但我以前一直认为这是一个误解,汗自己一把;
另外,当我们使用证书的时候,比如pfx、cer、jks、rsa等,从中我们可以看出私钥比公钥暴露出了更多的信息,大家可以自行导出xml查看,当然其中很多参数是用来加速的,根本的信息还是密钥;
比如公钥导出格式为:
<RSAKeyValue>
<Modulus>...</Modulus>
<Exponent>...</Exponent>
</RSAKeyValue>
私钥导出格式为:
<RSAKeyValue>
<Modulus>...</Modulus>
<Exponent>...</Exponent>
<P>...</p>
<Q>...</q>
<DP>...</DP>
<DQ>...</DQ>
<InverseQ>...</InverseQ>
<D>...</D>
</RSAKeyValue>
数字签名与私钥加密
数字签名:就是只有信息的发送者才能产生的,别人无法伪造的一段数字串,它同时也是对发送者发送的信息的真实性的一个证明。
对一段信息进行签名时,一般会先用哈希函数计算出被签名信息惟一的哈希结果值(为实用目的,降低加密成本,RSA加密不适用于大数据量加密).最后使用私钥将哈希结果值转化为数字签名.得到的数字签名对于被签名的信息和用以创建数字签名的私钥而言都是独一无二的。
按照上面的说法,数字签名=私钥加密(hash(原始数据));但是我用相同的原始数据、相同的hash算法、相同的密钥分别进行计算得到的结果却是不一致的,所以我一直怀疑这个描述有问题?
对此,我search了很多,ch的,en的,但都没有找到一个让我信服的解释,大多都是如上的这种解释;最后还是求助于官方描述文档RFC 2313,下面就看看数字签名到底是怎么回事:
数字签名包括4个步骤:消息散列,DER数据编码,RSA私钥加密和字节串到位串的转换。
这样也就可以解释上面的公式为什么两边运算的结果不一致了,因为中间少了很多运算;之后我也下载了bouncycastle的jce实现源码来看,过程的确如此;
关于DER数据编码,这个会在后续文章中详述,他是一个遵循ASN.1规范的编码规范;
数字签名的验证过程
我们在验证数字签名的时候,一般会将签名数据、原始数据、公钥一起作为参数输入,返回验证true或false;这样便造成了一种假象,如上面所说的:公钥是不能解密的!但是实际验证过程却不是这样的;
同样的,他完全是数字签名的逆向过程,来看看RFC的官方描述,验证过程包括四个步骤:位串到字节串的转换,RSA公钥解密,DER数据解码,得到解密后的散列值,最后与原始数据散列值进行比较,若每一位都相同则返回true,否则返回false;