速通python加密之RSA加密

发布于:2025-07-28 ⋅ 阅读:(15) ⋅ 点赞:(0)

RSA加密

RSA加密是一种非对称加密算法(与AES等对称加密不同),由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)于1977年提出,名字取自三人姓氏首字母。它通过一对密钥(公钥和私钥) 实现加密和解密,是目前应用最广泛的非对称加密技术之一。

核心特点:

  1. 非对称密钥体系

    • 公钥:可公开传播,用于加密数据或验证签名。
    • 私钥:必须保密,用于解密公钥加密的数据,或生成签名。
      核心逻辑:用公钥加密的数据,只有对应的私钥能解密;用私钥加密的数据(签名),只有对应的公钥能验证。
  2. 安全性基础
    基于大数分解难题:将两个大质数相乘容易,但要分解其乘积(得到原始质数)在计算上几乎不可行。密钥长度越长(如2048位、4096位),破解难度呈指数级增长,目前2048位及以上被认为足够安全。

  3. 加密与解密效率
    因涉及复杂的大数运算,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,你是??


网站公告

今日签到

点亮在社区的每一天
去签到