-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFile_encryption.py
More file actions
185 lines (141 loc) · 4.57 KB
/
File_encryption.py
File metadata and controls
185 lines (141 loc) · 4.57 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import hashlib
import pickle
import random
import math
import time
import Large_Prime_Generation
def str_to_int(string):
return int.from_bytes(string.encode('utf-8'), 'big')
# 将整数解码为字符串
def int_to_str(integer):
return integer.to_bytes((integer.bit_length() + 7) // 8, 'big').decode('utf-8')
def bytes_to_int(byte):
return int.from_bytes(byte, 'big')
def int_to_bytes(integer):
return integer.to_bytes((integer.bit_length() + 7) // 8, 'big')
# 加密
def encrypt(p, g, y, plaintext):
plaintext_int = bytes_to_int(plaintext)
# 随机选择一个数作为加密因子k
k = random.randint(2, p - 2)
# 计算密文
a = pow(g, k, p)
b = (plaintext_int * pow(y, k, p)) % p
# 返回密文
return (a, b)
# 解密
def decrypt(p, x, ciphertext):
a, b = ciphertext
# 计算明文
plaintext_int = (b * pow(a, p - 1 - x, p)) % p
# 返回明文
plaintext = int_to_bytes(plaintext_int)
return plaintext
# 优化2:选择范围为[1, p-2]的随机数
def secure_random(p):
return random.randint(1, p - 2)
# 优化4:使用扩展欧几里得算法加速私钥生成
def generate_keys_fast(p, g):
# 选择一个随机数k
k = secure_random(p)
# 使用扩展欧几里得算法计算私钥x和模反元素inv_k
d, x, inv_k = extended_euclidean_algorithm(k, p - 1)
# 计算公钥y
y = pow(g, x, p)
# 返回公钥和私钥
return (y, x)
# 扩展欧几里得算法
def extended_euclidean_algorithm(a, b):
if b == 0:
return (a, 1, 0)
else:
d, x, y = extended_euclidean_algorithm(b, a % b)
return (d, y, x - (a // b) * y)
# 快速幂
def fast_power(base, exponent, modulus):
result = 1
while exponent > 0:
if exponent % 2 == 1:
result = (result * base) % modulus
exponent = exponent // 2
base = (base * base) % modulus
return result
# 加密
def encryptfast(p, g, y, plaintext):
plaintext_int = bytes_to_int(plaintext)
# 随机选择一个数作为加密因子k
k = secure_random(p)
# 计算密文
a = pow(g, k, p)
b = (plaintext_int * pow(y, k, p)) % p
# 返回密文
return (a, b)
# 解密
def decryptfast(p, x, ciphertext):
a, b = ciphertext
# 计算明文
inv_a = fast_power(a, p - 1 - x, p)
plaintext_int = (b * inv_a) % p
# 返回明文
plaintext = int_to_bytes(plaintext_int)
return plaintext
# 选择范围为[1, p-2]的随机数
def secure_random(p):
return random.randint(1, p - 2)
def file_encrypt(file, p, g, public_key):
start_time = time.time()
with open(file, 'rb') as f:
plain_text = f.read()
cipher_text = [file]
length = 64
# print(plain_text)
for i in range(0, len(plain_text), length):
# print(plain_text[i:i + length])
cipher_text.append(encryptfast(p, g, public_key, b'%'+plain_text[i:i + length]))
new_path = file.rsplit(".", 1)[0] + "_encrypted" + "." + file.rsplit(".", 1)[1]
# print(cipher_text)
with open(new_path, 'wb') as f:
pickle.dump(cipher_text, f)
end_time = time.time()
print("encrypted")
print(f"Time taken: {end_time - start_time:.3f} seconds")
def file_decrypt(file, p, private_key):
f = open(file, "rb")
ciphered_text = pickle.load(f)
# print(ciphered_text)
path = ciphered_text[0]
new_path = path.rsplit(".", 1)[0] + "_decrypted" + "." + path.rsplit(".", 1)[1]
start_time = time.time()
plain_text = b''
for item in ciphered_text[1:]:
plain_text += decryptfast(p, private_key, item)[1:]
# print(plain_text)
with open(new_path, "wb") as f:
f.write(plain_text)
end_time = time.time()
print("decrypted")
print(f"Time taken: {end_time - start_time:.3f} seconds")
def en_and_de(file):
p = Large_Prime_Generation.generate_prime()
g = 2
public_key, private_key = generate_keys_fast(p, g)
new_path = file.rsplit(".", 1)[0] + "_encrypted" + "." + file.rsplit(".", 1)[1]
file_encrypt(file, p, g, public_key)
file_decrypt(new_path, p, private_key)
res_path = file.rsplit(".", 1)[0] + "_decrypted" + "." + file.rsplit(".", 1)[1]
with open(file, 'rb') as fp:
data = fp.read()
file_md5 = hashlib.md5(data).hexdigest()
with open(res_path, 'rb') as new_fp:
new_data = new_fp.read()
new_file_md5 = hashlib.md5(new_data).hexdigest()
# print(file_md5)
# print(new_file_md5)
if file_md5 == new_file_md5:
print("success")
else:
print("fail")
if __name__ == '__main__':
#输入文件地址
file = "1.txt"
en_and_de(file)