RSA常用场景是:
1)生成公钥、私钥
2)公钥加密,私钥解密
3)私钥签名,公钥验签(返回成功or失败)
以上场景实现比较简单,网上大把的文章,大部分加密库也都支持,我不再赘述。
如果你遇到稀有场景4:
私钥加密,公钥解密(返回明文):只拿到公钥,没有私钥
百度和谷歌发现大部分文章给不了答案,浪费了很多时间
那么不妨阅读一下本文章,或许可以得到答案或者启发。
一、pycrypto 没能解决问题,但指出了可能解决的方向weixin_xyyqwl的博客_CSDN博客-性能,android,微服务、持续集成领域博主
1、Package Crypto
https://www.dlitz.net/software/pycrypto/api/current/Crypto-module.html
cryto有3个子包和RSA相关
2、Cipher在讲对称、非对称加密算法
Crypto.Cipher.PKCS1_v1_5: 最接近目标场景4,但点进去却是场景2。
3、同理阅读其他子包,也不满足场景4需求
4、首页指出了方向weixin_xyyqwl的博客_CSDN博客-性能,android,微服务、持续集成领域博主
This software is no longer maintained. | PyCrypto
意思是pycrypto不再维护,被弃用,存在安全缺陷。如果新建代码,建议使用Cryptography
如果是维护老的pycrypto项目,建议使用PyCryptodome
weixin_xyyqwl的博客_CSDN博客-性能,android,微服务、持续集成领域博主
二、cryptography
Welcome to pyca/cryptography — Cryptography 38.0.0.dev1 documentation
1、找到RSA的位置
RSA — Cryptography 38.0.0.dev1 documentation
2、基于左侧导航栏,找到RSA公钥类
3、阅读公钥类的所有方法,recover_data_from_signature(signature, padding, algorithm)满足场景4:私钥加密,公钥解密(返回明文)weixin_xyyqwl的博客_CSDN博客-性能,android,微服务、持续集成领域博主
4、那么怎样得到公钥类呢?weixin_xyyqwl的博客_CSDN博客-性能,android,微服务、持续集成领域博主
第3种构造方式,满足场景4需求:只拿到公钥,没有私钥
5、准备工作完毕,开始动手了,安装库
Installation — Cryptography 38.0.0.dev1 documentation
pip install cryptography
pip install --upgrade cryptography
6、写代码weixin_xyyqwl的博客_CSDN博客-性能,android,微服务、持续集成领域博主
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
import cryptography.hazmat.primitives.asymmetric.padding
#https://blog.csdn.net/weixin_51380973
#行1:输入公钥Modulus(n) https://blog.csdn.net/weixin_51380973
n=int("BDBD8C45497213D6C11078DDAD11F2648213D9C91741DFFD8A036D118D75D06439A4E3647A39ECB18852D38C2469F97092823EA4C7527ECFA3EE26CCBE5883E2E2415DAB02ED57FD5A0AA074FF0CCAA3E5C12AE0D94FFD971F5F1B68D6DA789E64E3ACAF7638EC9A80AB186A4E7349C1EE75A6DA2A265286463956FF03BADA419E5D006D54B617284A30DE345DC0EC1CB08F838C7044CC913C057B2648AB07A1375D16C24581888159AA45F4DA4402D3B37F9BA6CF4FCC7550B1BF09C18132F6420408BED63C882060F07C9DDC5997866F2FCC5BDC335A6B55F379BC77E66508D91E852ECF39A57A1A92410775025C287188A4B4CFD073B2E68CE9851AFBE63F",16)
#行2:输入公钥指数Public Exp(e) https://blog.csdn.net/weixin_51380973
e=int("0x010001",16)
#行3、4:获取公钥https://blog.csdn.net/weixin_51380973
pbn=RSAPublicNumbers(e,n)
puk=pbn.public_key()
#行5:输入私钥加密后的数据https://blog.csdn.net/weixin_51380973 signature=bytes.fromhex("96E66624B6F87A186CA40EA55D4122B64DDF511AF30F283BEF3D474BEE2B9FAABC9193AFA805D55D2A1EF48C4E7DC39523934C08A0D1A98A96EB23F0E814AC8E7FAFA1D35ACA2C66D63CEEFEF6A237F2B0842FE8F6A426599228EABBEC82A71D57EA63EF9D98DDA01F728EE40B10EC42B83534A31B9C7758403E02D2DB82C25D7DD2AAF0C6E01D6869DF53C8B43C5131A52C4E94C2539F6C5D45766B56280AA7FFE9BDFF0D0C795AA56583D9313027FED88F27347229D8E9C92510E642EACE3756C8BBA0A243A988D8F739151B95EDEB0A3F8012CC1AC7E35DF2842D8E555734DFDC1C94933860E8087D083534A8C75F85759C37D12E001DE1B89B17765FFC45")
#行6:输入填充模式padding mode https://blog.csdn.net/weixin_51380973
padding=cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15()
#行7:输入算法https://blog.csdn.net/weixin_51380973
algorithm=None
#行8:得到原始二进制数据https://blog.csdn.net/weixin_51380973
bdata=puk.recover_data_from_signature(signature, padding, algorithm)
#行9:转成16进制大写数据https://blog.csdn.net/weixin_51380973
hdata=bdata.hex().upper()
#https://blog.csdn.net/weixin_51380973