RSA 加密算法是一种非对称加密算法,在公开密钥加密和电子商业中被广泛使用。RSA 是 1977 年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA 就是他们三人姓氏开头字母拼在一起组成的。

到当前为止,世界上还没有任何可靠的攻击 RSA 算法的方式。只要其钥匙的长度足够长,用 RSA 加密的信息实际上是不能被破解的。

当然,一般情况下使用 morse code 也是可以的,毕竟也不是所有人都看得懂 (lǎn de kàn)../.----./--//-.-/.-.././../.../-

公钥与私钥的产生

假设 A 想要通过一个不可靠的媒体接收 B 的一条私人讯息。他可以用以下的方式来产生一个公钥和一个私钥:

  1. 随意选择两个大的质数 不等于 ,计算
  2. 根据欧拉函数,求得
  3. 选择一个小于 的整数 ,使 互质。并求得 关于 的模反元素,命名为 (求 )。(模反元素存在,当且仅当 互质)
  4. 的记录销毁。

是公钥, 是私钥。A 将他的公钥 传给 B,而将他的私钥 藏起来。此时 B 用公钥 加密文件或消息并传给 A,A 即可用私钥 解密。

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#coding=utf-8

from Crypto.PublicKey import RSA
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES, PKCS1_OAEP
import os,sys
import base64

def CreateRSAKeys():
code = 'YourPasswordHere'
key = RSA.generate(2048)
encrypted_key = key.exportKey(passphrase=code, pkcs=8, protection="scryptAndAES128-CBC")
# 私钥
with open('my_private_rsa_key.bin', 'wb') as f:
f.write(encrypted_key)
# 公钥
with open('my_rsa_public.pem', 'wb') as f:
f.write(key.publickey().exportKey())
def Encrypt(filename):
data = ''
with open(filename, 'rb') as f:
data = f.read()
with open(filename, 'wb') as out_file:
# 收件人秘钥 - 公钥
recipient_key = RSA.import_key(open('my_rsa_public.pem').read())
session_key = get_random_bytes(16)
# Encrypt the session key with the public RSA key
cipher_rsa = PKCS1_OAEP.new(recipient_key)
out_file.write(cipher_rsa.encrypt(session_key))
# Encrypt the data with the AES session key
cipher_aes = AES.new(session_key, AES.MODE_EAX)
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
out_file.write(cipher_aes.nonce)
out_file.write(tag)
out_file.write(ciphertext)

def Descrypt(filename):
code = 'YourPasswordHere'
with open(filename, 'rb') as fobj:
private_key = RSA.import_key(open('my_private_rsa_key.bin').read(), passphrase=code)
enc_session_key, nonce, tag, ciphertext = [ fobj.read(x)
for x in (private_key.size_in_bytes(),
16, 16, -1) ]
cipher_rsa = PKCS1_OAEP.new(private_key)
session_key = cipher_rsa.decrypt(enc_session_key)
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
data = cipher_aes.decrypt_and_verify(ciphertext, tag)

with open(filename, 'wb') as wobj:
wobj.write(data)
def RenameFile(dir,filename):
filename_bytes = filename.encode('utf-8')
filename_bytes_base64 = base64.encodebytes(filename_bytes)

filename_bytes_base64 = filename_bytes_base64[::-1][1:]
new_filename = filename_bytes_base64.decode('utf-8') + '.crypt1'
print(os.path.join(dir, filename))
print(os.path.join(dir,new_filename))
os.rename(os.path.join(dir, filename), os.path.join(dir,new_filename))
def ReserveFilename(dir, filename):
f = filename
filename = filename[::-1][7:][::-1]
filename_base64 = filename[::-1] + '\n'
filename_bytes_base64 = filename_base64.encode('utf-8')
ori_filename = base64.decodebytes(filename_bytes_base64).decode('utf-8')
print(os.path.join(dir, f))
print(os.path.join(dir,ori_filename))
os.rename(os.path.join(dir, f),os.path.join(dir,ori_filename))

def Main(rootDir):
list_dirs = os.walk(rootDir)
for root, dirs, files in list_dirs:
# 切换加密和解密过程
#if False:
if (sys.argv[1] == 'encode'):
# 遍历文件,加密并且改名
for f in files:
filename = os.path.join(root, f)
Encrypt(filename)
RenameFile(root, f)
elif (sys.argv[1] == 'decode'):
# 遍历文件,解密并且恢复名字
for f in files:
filename = os.path.join(root, f)
Descrypt(filename)
ReserveFilename(root, f)

if __name__ == '__main__':
#CreateRSAKeys() #第一次运行需要去掉注释
d = '/root/RSA/files/'
Main(d)

使用前需要安装依赖,在 terminal 输入pip3 install PyCryptodome
使用时将需要加密的文件放入d = '/root/RSA/files/'所示目录,并在 RSA.py 所在目录终端输入python3 RSA.py [option: encode & decode]

使用演示_encode
使用演示_decode