python中的RSA加密与解密实例解析
这篇文章主要介绍了pythonRSA加密与解密实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
什么是RSA:
RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止2017年被普遍认为是最优秀的公钥方案之一。
SET(SecureElectronicTransaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。RSA密钥长度随着保密级别提高,增加很快。下表列出了对同一安全级别所对应的密钥长度。
python实现对RSA的加密和解密
Python密码库--Pycrypto
Python良好的生态,对于加密解密技术都有成熟的第三方库。大名鼎鼎的M2Crypto和Pycrypto,前者非常容易使用,可是安装却非常头疼,不同的系统依赖软件的版本还有影响。后者则比较方面,直接使用pip安装即可。
密码技术
为了进行加密以及通信,人们发明了很多公开的算法。对称与非对称算法等。常见的加密方式有RSA,AES等算法。对于选择加密算法,一个常识就是使用公开的算法。一方面是这些算法经过实践检验,另一方面对于破译难度和破译条件破译时间都有预估。对于任何加密算法,都是能破解的,不同在于时间上的投入。
Python密码库--Pycrypto
Python良好的生态,对于加密解密技术都有成熟的第三方库。大名鼎鼎的M2Crypto和Pycrypto,前者非常容易使用,可是安装却非常头疼,不同的系统依赖软件的版本还有影响。后者则比较方面,直接使用pip安装即可。
安装
pipinstallpycrypto
RSA密码算法与签名
RSA是一种公钥密码算法,RSA的密文是对代码明文的数字的E次方求modN的结果。也就是将明文和自己做E次乘法,然后再将其结果除以N求余数,余数就是密文。RSA是一个简洁的加密算法。E和N的组合就是公钥(publickey)。
对于RSA的解密,即密文的数字的D次方求modN即可,即密文和自己做D次乘法,再对结果除以N求余数即可得到明文。D和N的组合就是私钥(privatekey)。
算法的加密和解密还是很简单的,可是公钥和私钥的生成算法却不是随意的。本文在于使用,对生成秘钥对的算法就暂时忽略。使用Pycrypto生成秘钥对很简单,我们分别为Server和Client各生成一对属于自己的秘钥对。
fromCryptoimportRandom fromCrypto.HashimportSHA fromCrypto.CipherimportPKCS1_v1_5asCipher_pkcs1_v1_5 fromCrypto.SignatureimportPKCS1_v1_5asSignature_pkcs1_v1_5 fromCrypto.PublicKeyimportRSA #伪随机数生成器 random_generator=Random.new().read #rsa算法生成实例 rsa=RSA.generate(1024,random_generator) #Server的秘钥对的生成 private_pem=rsa.exportKey() withopen("server-private.pem","w")asf: f.write(private_pem) public_pem=rsa.publickey().exportKey() withopen("server-public.pem","w")asf: f.write(public_pem) #Client的秘钥对的生成 private_pem=rsa.exportKey() withopen("client-private.pem","w")asf: f.write(private_pem) public_pem=rsa.publickey().exportKey() withopen("client-public.pem","w")asf: f.write(public_pem)
所生成的私钥和公钥大概是这样的:
-----BEGINRSAPRIVATEKEY----- MIICXQIBAAKBgQC26X6A0WCWiVxdxq3jtm42yDdGbf+99v2zyi0UMVGZfowlnkcW eMvpz8NBm2UVlrjZpnFr8wFkdHyjFFkq/ilclH3AN4+Xw8Ap7CGJ2jVMyS5h9RRB Uyf3F4D5Og8789Ywh9HXYyvD/6J62EtbbkhGPxg3aa8n2kfKZ9N6Q7DqrwIDAQAB AoGBAJn5qu1D1FxE24Vxl7ZGPzdMigN227+NaPptak9CSR++gLm2KL+JBpcXt5XF +20WCRvnWjl2QijPSpB5s6pWdHezEa1cl6WrqB1jDJd1U99WNCL5+nfEVD9IF+uE ig0pnj+wAT5fu78Z0UjxD9307f9S7BLC8ou3dWVkIqob6W95AkEAuPGTNlTkquu/ wBJTb4/+/2ZCf7Ci9qvsN3+RcrzFkKa3uTtBOa6Xk2R61zBkucUgY6cQHPbxhFLN TVmXdbwxTQJBAP0wGenVOq4dCPdz3NhyghkKT6SL2w/SgbrROiJ1mG9MoBq58/0g k85I91R7nuvOYTKTUkhWdPYITpDarmPJzesCQGRBmOMgHCHH0NfHV3Gn5rz+61eb IoyD4Hapceh4CsWCiyAfzhj9229sTecvdbr68Lb0zphVCdIIrQCca63IShUCQGYI e3jzmHlQdCudArQruWgz8pKiVf7TW7qY1O/MKkk4PRFoPP6WoVoxp5LhWtM20Y7b Nf628N2xzU+tAThvvE8CQQCI1C7GO3I5EMfqPbTSq2oZq8thvGlyFyI7SNNuvAHj hj2+0217B9CcTZqloYln01CNDVuaoUgEvFSw1OdRB1tC -----ENDRSAPRIVATEKEY----- -----BEGINPUBLICKEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC26X6A0WCWiVxdxq3jtm42yDdG bf+99v2zyi0UMVGZfowlnkcWeMvpz8NBm2UVlrjZpnFr8wFkdHyjFFkq/ilclH3A N4+Xw8Ap7CGJ2jVMyS5h9RRBUyf3F4D5Og8789Ywh9HXYyvD/6J62EtbbkhGPxg3 aa8n2kfKZ9N6Q7DqrwIDAQAB -----ENDPUBLICKEY-----
加密与解密
通常通信的时候,发送者使用接受者的公钥加密,接受者使用接受者私钥解密。
简而言之,Server给Client通信,需要加密内容,那么Client会生成一个秘钥对,Client的公钥client-public.pem和私钥client-private.pem。Client把公钥公开给发送者,任何人都可以用来加密,然后Server使用client-public.pem进行加密,然后把内容发给Client,Client再使用私钥client-private.pem进行解密。
1.加密(encrypt)
#Server使用Client的公钥对内容进行rsa加密 message="helloclient,thisisamessage" withopen("client-public.pem")asf: key=f.read() rsakey=RSA.importKey(key) cipher=Cipher_pkcs1_v1_5.new(rsakey) cipher_text=base64.b64encode(cipher.encrypt(message.encode('utf-8'))) print(cipher_text.decode('utf-8')) #加密结果: HYQPGB+axWCbPp7PPGNTJEAhVPW0TX5ftvUN2v40ChBLB1pS+PVM3YGT5vfcsvmPZhW8NKVSBp8FwjLUnMn6yXP1O36NaunUzyHwI+cpjlkTwZs3DfCY/32EzeuKuJABin1FHBYUMTOKtHy+eEDOuaJTnZTC7ZBkdha+J88HXSc=
cipher_text即Master加密后将要发送给Client的密文。
2.解密(decrypt)
#Client使用自己的私钥对内容进行rsa解密 withopen("client-private.pem")asf: key=f.read() rsakey=RSA.importKey(key) cipher=Cipher_pkcs1_v1_5.new(rsakey) text=cipher.decrypt(base64.b64decode(encrypt_text),random_generator) print(text.decode('utf-8')) #解密结果: helloclient,thisisamessage
这样Client就能看到Server所发的内容了,当然,如果Client想要给Server发消息,就需要Server先把其的公钥给Client,后者再使用公钥加密,然后发送给Server,最后Server使用自己的私钥解密。
签名与验签
当然,对于窃听者,有时候也可以对伪造Server给Client发送内容。为此出现了数字签名。也就是Server给Client发送消息的时候,先对消息进行签名,表明自己的身份,并且这个签名无法伪造。具体过程即Server使用自己的私钥对内容签名,然后Client使用Server的公钥进行验签。
签名
#Server使用自己的私钥对内容进行签名 withopen("server-private.pem")asf: key=f.read() rsakey=RSA.importKey(key) signer=Signature_pkcs1_v1_5.new(rsakey) digest=SHA.new() digest.update(message) sign=signer.sign(digest) signature=base64.b64encode(sign) printsignature #签名结果: jVUcAYfgF5Pwlpgrct3IlCX7KezWqNI5tD5OIFTrfCOQgfyCrOkN+/gRLsMiSDOHhFPj2LnfY4Cr5u4eG2IiH8+uSF5z4gUX48AqCQlqiOTLk2EGvyp+w+iYo2Bso1MUi424Ebkx7SnuJwLiPqNzIBLfEZLA3ov69aDArh6hQiw=
验签
#Client使用Server的公钥对内容进行验签 withopen("server-public.pem")asf: key=f.read() rsakey=RSA.importKey(key) verifier=Signature_pkcs1_v1_5.new(rsakey) digest=SHA.new() #Assumesthedataisbase64encodedtobeginwith digest.update(message) is_verify=signer.verify(digest,base64.b64decode(signature)) printis_verify #验签结果: True
总结
Pycrypto提供了比较完善的加密算法。RSA广泛用于加密与解密,还有数字签名通信领域。使用Publick/Private秘钥算法中,加密主要用对方的公钥,解密用自己的私钥。签名用自己的私钥,验签用对方的公钥。
- 加密解密:公钥加密,私钥解密
- 签名验签:私钥签名,公钥验签
无论是加密解密还是签名验签都使用同一对秘钥对。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。