数字签名主要有防抵赖和防篡改两种功能:一是能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名,二是能确定消息的完整性。
作为具体实现,发送报文时,发送方用一个哈希函数(例如MD5、SHA-1、SHA-256、SHA-384或SHA-512)从报文文本中生成报文摘要,然后用自己的私钥(由RSA或其他公钥密码体制算法生成,只有发送方本人知道,需保密)对这个摘要进行加密,这个加密后的摘要将作为报文的数字签名和报文一起发送给接收方,接收方首先用与发送方一样的哈希函数从接收到的原始报文中计算出报文摘要,接着再用发送方的公钥(必须与发送方的私钥配对使用,无法对其他人私钥加密的信息进行正确解密)来对报文附加的数字签名进行解密,如果能够正确解密并且这两个摘要相同、那么接收方就能确认该数字签名是发送方的。
下面的代码演示了Python扩展库rsa中数字签名的用法。
>>> import rsa
#生成配对的公钥和私钥
>>> publicKey, privateKey = rsa.newkeys(3000)
>>> message = 'Hello world.'
#签名,也可以指定其他哈希算法
>>> signature = rsa.sign(message.encode(), privateKey, 'MD5')
#验证签名
>>> print(rsa.verify(message.encode(), signature, publicKey))
True
#消息错误
>>> print(rsa.verify('message'.encode(), signature, publicKey))
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
print(rsa.verify('message'.encode(), signature, publicKey))
File "C:\Python 3.5\lib\site-packages\rsa\pkcs1.py", line 322, in verify
raise VerificationError('Verification failed')
rsa.pkcs1.VerificationError: Verification failed
#签名错误
>>> print(rsa.verify(message.encode(), signature+b'0', publicKey))
Traceback (most recent call last):
File "<pyshell#63>", line 1, in <module>
print(rsa.verify(message.encode(), signature+b'0', publicKey))
File "C:\Python 3.5\lib\site-packages\rsa\pkcs1.py", line 308, in verify
raise VerificationError('Verification failed')
rsa.pkcs1.VerificationError: Verification failed