速通python加密之RSA加密
RSA加密
RSA加密是一种非对称加密算法(与AES等对称加密不同),由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)于1977年提出,名字取自三人姓氏首字母。它通过一对密钥(公钥和私钥) 实现加密和解密,是目前应用最广泛的非对称加密技术之一。
核心特点:
-
非对称密钥体系
- 公钥:可公开传播,用于加密数据或验证签名。
- 私钥:必须保密,用于解密公钥加密的数据,或生成签名。
核心逻辑:用公钥加密的数据,只有对应的私钥能解密;用私钥加密的数据(签名),只有对应的公钥能验证。
-
安全性基础
基于大数分解难题:将两个大质数相乘容易,但要分解其乘积(得到原始质数)在计算上几乎不可行。密钥长度越长(如2048位、4096位),破解难度呈指数级增长,目前2048位及以上被认为足够安全。 -
加密与解密效率
因涉及复杂的大数运算,RSA加密速度远慢于对称加密(如AES),因此不适合加密大量数据,通常用于加密对称加密的密钥(即“混合加密”),或用于数字签名。
典型应用场景:
- 密钥交换:在HTTPS、VPN等通信中,用对方公钥加密对称加密的密钥,确保密钥安全传输(如TLS握手阶段)。
- 数字签名:发送方用私钥对数据哈希值加密(生成签名),接收方用公钥验证签名,确认数据未被篡改且来自合法发送方(如软件签名、电子合同)。
- 身份认证:通过验证私钥持有者的身份(如SSH登录用公钥认证)。
示例(生成公钥和私钥) :
"""
@File : 非对称加密RSA.py
@Editor : 百年
"""
'''
非对称加密,加密和解密的密钥不是同一个密钥,而是需要两把密钥
一个是公钥,一个是私钥,公钥发送给客户端,发送端用公钥对数据进行加密,
再发送给接收端,接收端使用私钥来对数据进行解密,
由于私钥只存放在接收端这边,
所以即使数据被截获了,也是无法进行解密的
常见的非对称加密算法:RSA,DSA
rsa是最常见的一种加密方案
公钥是用来加密的
私钥是用来解密的
密钥(私钥)不能公开
公钥和私钥是成对的,是有一定的关联的
加密和解密用的不是同一个密钥,私钥放在服务器上不公开
'''
from Crypto.PublicKey import RSA #这是处理密钥的
from Crypto import Random
import base64
# 生成密钥,默认生成的是私钥
key = RSA.generate(2048)
print(key)
# Private RSA key at 0x1D92A324690 生成了私钥,后面跟的是内存地址# print(key.export_key())
# print(key.exportKey()) #tips:这俩一样的
private_key = key.export_key()
# print(private_key)
#直接这样输出的是base64字节而且带有换行符
# 可以decode,将base64字节转换为b64字符串
print(private_key.decode())# private_key_b = key.export_key(format='DER') #输出纯字节的私钥
# print(private_key_b)#生成公钥puiblic_key = key.public_key()
print(puiblic_key)
# Public RSA key at 0x227A7D9ADD0
print(puiblic_key.export_key())
#这样打印也是有换行符的
print(puiblic_key.export_key().decode())
#还得decode
'''
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuTelupiUOptxRuq0HdXe
wvxw7mfpE45uxPGybbFWCykczUjthcsrnfe33zX6GikGN8O/h1Z2LGvslkupeGYB
mixLnTMTahL45P2o92szSb9xiixa50FrfFCwkkuCTcpHARkMDMawAIH+xt+bKjq9
DJKHXTaTpjrcaqXI38TYwMtGYRFJhOQr39B3P28UNAa03gKbajh4sRSA0WF6I8My
wdZZmmccW6q+rgZOs92UCwUTd4ZmzweU2FQeailhLrQWTbO9g/w9HLtFFgUWx6Vf
2WO8S5zEBPFHqbvh1Kjtvn9HK+w12uM7NDBdLgMg0PgU9AfGNzDj2pOU+drdPzbM
uwIDAQAB
-----END PUBLIC KEY-----
'''#这正使用过程中,服务器一开始就会直接写入到文件当中去#important:注意写入的是二进制
#写出私钥
with open('private.pem','wb') as f:f.write(key.export_key())#写出公钥
with open('public.pem','wb') as f1:f1.write(key.public_key().export_key())
示例(用公钥加密)
"""
@File : 使用自己的rsa密钥加密.py
@Editor : 百年
"""'''
加密流程是客户端最有用的地方
解密流程是发生在服务器端的
'''from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64#step1 :加载密钥,需要的是公钥,公钥是用来加密的
#这里用我们上一个文件中生成的公钥
#export是导出,那么我们就可以用import进行导入
# tips: 可以读字节import_key(b'b64密钥',),也可以读字符串
pub_k = RSA.import_key(open('public.pem','rb').read())
#step2 :创建加密器的流程和之前的AES,DES很像
rsa = PKCS1_v1_5.new(key=pub_k)#step3 :进入加密逻辑
s = 'hello,我叫hero,你是??'
enc_s = rsa.encrypt(s.encode('utf-8'))print(enc_s)
#打印出来是混乱字节
#step4 :为了传输,需要利用base64进行编码enc_s = base64.b64encode(enc_s)
print(enc_s.decode())
#important:rsa加密后的东西,如果不是纯数学算法,每次都是随机的
'''
FfXEjq4Uy3zikwtTMVw+q9HqmhSyoMkUjI/VaA/JrKkp/gdLgqlKCg+0s+dttvtlDKdLE2L+WD0hseEFXhSo7hVo3aQyevtzOAokZY0ZM5Anq+hQSt4EyBxnco7ABe3iCYTJuUEqWIw0bnUB+Fq9tRshDwKsBwNCKQ2TBjM8QSUmcGa9Zvy/pdY4sPM9FGKe3vYcsejnmAbnp3llIcquSjO+clUrCI9/4HDB2bB5yxw4trxVtDukxtMWYZgyYDBvW1waL6i70h9F7/blTNSJiE5GSfktENHXY1tQsQuSpQx9N7N8sLLpIDMmmFfqv122GPncbA1zz7eoGU/Vncopkg=='''
示例(用私钥解密):
"""
@File : 使用私钥进行解密.py
@Editor : 百年
"""
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64#密文
miwen = 'FfXEjq4Uy3zikwtTMVw+q9HqmhSyoMkUjI/VaA/JrKkp/gdLgqlKCg+0s+dttvtlDKdLE2L+WD0hseEFXhSo7hVo3aQyevtzOAokZY0ZM5Anq+hQSt4EyBxnco7ABe3iCYTJuUEqWIw0bnUB+Fq9tRshDwKsBwNCKQ2TBjM8QSUmcGa9Zvy/pdY4sPM9FGKe3vYcsejnmAbnp3llIcquSjO+clUrCI9/4HDB2bB5yxw4trxVtDukxtMWYZgyYDBvW1waL6i70h9F7/blTNSJiE5GSfktENHXY1tQsQuSpQx9N7N8sLLpIDMmmFfqv122GPncbA1zz7eoGU/Vncopkg=='#step1:因为是base64字符串,先将其转换为字节
b_s = base64.b64decode(miwen)
print(b_s)#构建解密器,对其进行解密
#step2:读取自己的私钥,但其实我们一般不考虑解密的事情,这是交给服务器端的pri_k = RSA.import_key(open('private.pem','rb').read())
# pri_k = RSA.import_key(k) 或者直接写的话就导入字节格式的密钥
rsa = PKCS1_v1_5.new(key=pri_k)
s = rsa.decrypt(b_s,sentinel='None') #important:注意这里要求要有一个位置参数表示报错后该参数执行,是规定,虽然用不到但是也要强制指定
print(s)
# b'hello,\xe6\x88\x91\xe5\x8f\xabhero,\xe4\xbd\xa0\xe6\x98\xaf??'#step3:还原
print(s.decode()) #tips:因为默认是utf-8,这里就不指定了
# hello,我叫hero,你是??