RSA篇

代码

库调用

pip install pycryptodome

关于填充的说明

PyCryptodome 库为 RSA 加密提供了 PKCS#1 OAEP 和 PKCS#1 v1.5 两种填充方案

PKCS#1 OAEP

使用哈希函数(如SHA-1、SHA-256)和随机数进行复杂编码

PKCS#1 v1.5 (旧版)

00 || 02 || [至少8字节的非零随机数] || 00 || 明文

留意Bleichenbacher攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import base64
def generate_rsa_keys():
# key = RSA.generate(2048)
key = RSA.generate(1024)
private_key = key.export_key()
public_key = key.publickey().export_key()
return private_key, public_key

def encrypt_rsa(public_key_pem, plaintext):
rsa_key = RSA.import_key(public_key_pem)
cipher = PKCS1_OAEP.new(rsa_key)
ciphertext = cipher.encrypt(plaintext.encode('utf-8'))
return base64.b64encode(ciphertext).decode('utf-8')

def decrypt_rsa(private_key_pem, ciphertext_b64):
rsa_key = RSA.import_key(private_key_pem)
cipher = PKCS1_OAEP.new(rsa_key)
encrypted_data = base64.b64decode(ciphertext_b64)
decrypted_data = cipher.decrypt(encrypted_data)
return decrypted_data.decode('utf-8')

if __name__ == "__main__":
private_key_pem, public_key_pem = generate_rsa_keys()
print("Private Key:\n", private_key_pem.decode())
print("Public Key:\n", public_key_pem.decode())

message = "re100dayzhuji"
print(f"原始消息: {message}")

encrypted_msg_b64 = encrypt_rsa(public_key_pem, message)
print(f"加密后的数据 (Base64): {encrypted_msg_b64}")

decrypted_msg = decrypt_rsa(private_key_pem, encrypted_msg_b64)
print(f"解密后的消息: {decrypted_msg}")

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import math
import random
def prime_init(max_num):
prime_num=[]
for i in range(2,max_num):
tmp=0
s=int(math.sqrt(i))+1
for j in range(2,s):
if i%j==0:
tmp=1
break
if tmp==0:
prime_num.append(i)
return prime_num
def key_init():
prime_num=prime_init(500)
print(prime_num)
while True:
string=input("选择两个素数: ").split(' ')
p,q=[int(x) for x in string]
if (p in prime_num) and (q in prime_num):
break
else:
print("输入错误")
N=p*q
r=(p-1)*(q-1)
r_prime=prime_init(r)
r_len=len(r_prime)
e=r_prime[random.randint(0,r_len-1)]
d=0
for n in range(2,r): #遍历找私钥
if(e*n)%r==1:
d=n
break
return (N,e),(N,d)

def encode(pub_key,m):
N,e=pub_key
return pow(m,e,N)

def decode(pri_key,m):
N,d=pri_key
return pow(m,d,N)

pub_key,pri_key=key_init()
print('公钥:',pub_key,'\n私钥:',pri_key)
m='re100dayzhuji'
enc=[encode(pub_key,ord(i)) for i in m]
print('加密后:')
s1=''.join(f'{x:02x}' for x in enc)
print(s1)
dec=[chr(decode(pri_key,i)) for i in enc]
print('解密后:')
s2=''.join(dec)
print(s2)
# 选择两个素数: 13 43
# 公钥: (559, 257)
# 私钥: (559, 353)
# 加密后:
# 861fffb1d1d16f917f87ea341721a1
# 解密后:
# re100dayzhuji

解密技巧

https://blog.csdn.net/qq_46145027/article/details/125047313


RSA篇
https://alenirving.github.io/2025/09/23/RSA篇/
作者
Ma5k
许可协议
CC-BY-NC-SA