-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
244 lines (179 loc) · 6.8 KB
/
main.cpp
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#include <iostream>
#include <iomanip>
#include "generatePrimeNumber.h"
#include "generateKey.h"
#include "enAndDecryptionRSA.h"
#include "RSAES-PKCS1-V1_5.h"
#include "RSAES-OAEP.h"
using namespace std;
void print_title(const std::string &title) ; //打印标题
void print_hex(const std::string &message) ; //十六进制打印字符串
//测试PKCS1 v1.5填充
void test5();
//测试OAEP填充
void test6();
gmp_randstate_t state;
int main() {
// 生成大随机素数2048bits
print_title("Generate random prime number:");
test1();
cout << "\n\n\n";
// 生成RSA密钥(公钥e,n和私钥d)
print_title("Generate RSA keys:");
test2();
cout << "\n\n\n";
// 基于整数的加密
print_title("Encryption and decryption based on a big int:");
test3();
cout << "\n\n\n";
// 基于字符串的加密
print_title("Encryption and decryption based on an English-String:");
test4();
cout << "\n\n\n";
//基于PKCS1 v1.5填充的加解密
print_title("PKCS1-V1.5 padding:");
test5();
cout<<"\n\n\n";
//基于OAEP填充的加解密
print_title("OAEP padding:");
test6();
cout<<"\n\n\n";
return 0;
}
//打印标题
void print_title(const std::string &title) {
int length = title.size();
// 输出上边框
std::cout << " ";
for (int i = 0; i < length + 4; ++i) {
std::cout << "-";
}
std::cout << "\n";
// 输出标题行
std::cout << "| " << title << " |\n";
// 输出下边框
std::cout << " ";
for (int i = 0; i < length + 4; ++i) {
std::cout << "-";
}
std::cout << "\n";
}
//十六进制打印字符串
void print_hex(const std::string &message) {
std::cout << "\nMessage in hex: \n";
for (unsigned char c : message) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)c << " ";
}
std::cout << std::endl;
}
// 测试PKCS1 v1.5填充
void test5() {
mpz_t n, e, d, ciphertext;
mpz_inits(n, e, d, ciphertext, nullptr);
init_random_state();
generate_rsa_key(2048, n, e, d);
std::string message = "Hello I'm 3klxi, a student from BeiJing Jiaotong University, cyber safety academy";
std::cout << "Original Message: \n" << message << std::endl;
std::cout<<endl;
print_hex(message);
// PKCS1 v1.5 填充并加密
auto padded_message_pkcs1 = pkcs1_v1_5_pad(message, 256);
std::cout << "\nPadded message (PKCS1 v1.5): \n";
for (unsigned char byte : padded_message_pkcs1) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " ";
}
std::cout << std::endl;
//填充后转化为mpz大整数
mpz_t padded_mpz_pkcs1;
mpz_init(padded_mpz_pkcs1);
pad_message_to_mpz(padded_mpz_pkcs1, padded_message_pkcs1);
std::cout << "\nTransform to big int(mpz): ";
gmp_printf("\n%Zd\n\n",padded_mpz_pkcs1);
//加密
mpz_powm(ciphertext, padded_mpz_pkcs1, e, n);
std::cout << "\n";
gmp_printf("\nCiphertext (PKCS1 v1.5): \n%Zd\n", ciphertext);
//将解密,存入decrypted_message_mpz
mpz_t decrypted_message_mpz;
mpz_init(decrypted_message_mpz);
mpz_powm(decrypted_message_mpz, ciphertext, d, n);
std::cout << "\n";
gmp_printf("\nDecryptiontext (PKCS1 v1.5): \n%Zd\n", decrypted_message_mpz);
// 将解密后的 mpz_t 转换为字节数组并输出
std::vector<unsigned char> decrypted_padded_message = mpz_to_padded_message(decrypted_message_mpz, 256);
std::cout << "\nDecrypted padded message: \n";
for (unsigned char byte : decrypted_padded_message) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " ";
}
std::cout << "\n\n";
// 去除 PKCS1 v1.5 填充
std::string final_decrypted_message;
try {
final_decrypted_message = pkcs1_v1_5_unpad(decrypted_padded_message);
std::cout << "\nDecrypted Message (PKCS1 v1.5): \n" << final_decrypted_message << std::endl;
if (message == final_decrypted_message) {
std::cout << "Decryption successful: Yes.\n" << std::endl;
} else {
std::cout << "Decryption successful: No.\n" << std::endl;
}
} catch (const std::runtime_error &e) {
std::cout << "Error during padding removal: " << e.what() << std::endl;
}
mpz_clears(n, e, d, ciphertext, padded_mpz_pkcs1, decrypted_message_mpz, nullptr);
}
//测试OAEP填充
void test6() {
mpz_t n, e, d, ciphertext;
mpz_inits(n, e, d, ciphertext, nullptr);
generate_rsa_key(2048, n, e, d);
std::string message = "Hello I'm 3klxi, a student from BeiJing Jiaotong University, cyber safety academy";
std::cout << "Original Message: \n" << message << std::endl;
std::cout << "\nOriginal Message in Hex: ";
for (char ch : message) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)(unsigned char)ch << " ";
}
std::cout << std::endl;
// OAEP 填充
auto padded_message = oaep_pad(message, 256);
std::cout << "\nOAEP Padded Message: \n";
for (unsigned char byte : padded_message) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " ";
}
std::cout << std::endl;
// 填充后转化为 mpz_t
mpz_t padded_mpz;
mpz_init(padded_mpz);
pad_message_to_mpz(padded_mpz, padded_message);
std::cout << "\nTransform to big int (mpz): ";
gmp_printf("\n%Zd\n\n", padded_mpz);
// 加密
mpz_powm(ciphertext, padded_mpz, e, n);
std::cout << "\nCiphertext (OAEP): ";
gmp_printf("\n%Zd\n", ciphertext);
// 解密,存入 decrypted_message_mpz
mpz_t decrypted_message_mpz;
mpz_init(decrypted_message_mpz);
mpz_powm(decrypted_message_mpz, ciphertext, d, n);
std::cout << "\nDecrypted Ciphertext to Big Int (OAEP): ";
gmp_printf("\n%Zd\n", decrypted_message_mpz);
// 将解密后的 mpz 转换为字节数组
auto decrypted_padded_message = mpz_to_padded_message(decrypted_message_mpz, 256);
std::cout << "\nDecrypted Padded Message: \n";
for (unsigned char byte : decrypted_padded_message) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " ";
}
std::cout << std::endl;
// 去除 OAEP 填充
try {
std::string decrypted_message = oaep_unpad(decrypted_padded_message);
std::cout << "\nDecrypted Message (OAEP): \n" << decrypted_message << std::endl;
if (message == decrypted_message) {
std::cout << "\nDecryption successful: Yes.\n" << std::endl;
} else {
std::cout << "\nDecryption successful: No.\n" << std::endl;
}
} catch (const std::runtime_error &e) {
std::cout << "Error during OAEP unpadding: " << e.what() << std::endl;
}
mpz_clears(n, e, d, ciphertext, padded_mpz, decrypted_message_mpz, nullptr);
}