基于公钥体制的RSA算法为信息安全传输的问题提供了新的解决思路和技术,也被用作数字签名方案,在实现消息认证方面得到了深入的应用。总的来说,RSA公钥签名方案包括消息空间、参数生成算法、签名算法和验证算法等部分。签名和验证的过程具体包括消息摘要的生成、大素数和密钥的生成以及消息签名、消息验证等几个步骤。
传统的签名方案使用RSA公钥算法进行数字签名,签名的过程如下:
(1)参数的选择和密钥的生成。
(2)用户A对消息M进行签名:
S=Sig(M)=M d mod n
其中,d是私钥,相当于用私钥进行加密运算(最好不要用“私钥加密”这种说法,而是采用“私钥签名”,否则容易和公钥加密混淆。加密就是加密,签名就是签名,两者的目的不同。私钥是为了签名,不是加密。有些算法库提供了私钥加密函数,实际上是私钥签名),然后将签名结果S作为用户A对消息M的数字签名附在消息M后面,发送给用户B。
(3)用户B验证用户A对M的数字签名S,计算M'=S e mod n。然后判断M'和M是否相等:若二者相等,则可以证明签名S的确来源于用户A;否则,签名S有可能为伪造的签名。例如,假设用户A选取p=823、q=953,那么模数n=784319、-(n)=(p-1)(q-1)=782544,然后选取e=313并计算出d=160009,则公钥为(313,784319)、私钥为(160009,784319)。如果用户A拟发送消息M=19070给用户B,就用私钥对消息进行签名:M:19070->S=(19070) 160009 mod 784319=210625 mod 78319。用户A将消息和签名同时发送给用户B,用户B接收消息和签名,并计算出M':
M'=210625 313 mod 784319=19070 mod 794319->M=M' mod n
因此,用户B验证了用户A的签名,并接收了消息。
在实际的应用过程中,待签名的消息一般都比较长,因此需要将消息明文先进行分组,再对不同的分组明文分别进行签名。这样会致使算法对于长文件签名的效率十分低下。为了解决这个问题,可以利用单项摘要函数(Hash函数),即在对消息进行签名之前事先使用Hash函数对需要签名的消息做Hash变换,对变换后的摘要消息再进行数字签名。
增加了Hash运算,则发送者要发送原文、原文的摘要值和摘要的数字签名值。这样接收者会收到原文、摘要和摘要的数字签名。接收者先对原文做摘要,然后和收到的摘要值做比较,如果一致,就说明原文没有被篡改过,接着用发送者的公钥对数字签名做验签,如果通过,就说明是发送者本人发来的(因为只有拥有私钥的发送者,才能签出这样一份数字签名)。