RabbitCommon v2.3.3
Loading...
Searching...
No Matches
EvpAES.cpp
1// Copyright Copyright (c) Kang Lin studio, All Rights Reserved
2// Author Kang Lin <kl222@126.com>
3
4#include "EvpAES.h"
5#include <openssl/evp.h>
6#include <openssl/aes.h>
7#include <openssl/ssl.h>
8
9#define KEY_SIZE_16B 16
10#define KEY_SIZE_24B 24
11#define KEY_SIZE_32B 32
12
13EvpAES::EvpAES()
14{
15 // 初始化CTX
16 ctx = EVP_CIPHER_CTX_new();
17 EVP_CIPHER_CTX_init(ctx);
18}
19
20EvpAES::~EvpAES()
21{
22 // 释放CTX
23 EVP_CIPHER_CTX_cleanup(ctx);
24 EVP_CIPHER_CTX_free(ctx);
25}
26
27bool EvpAES::ecb_encrypt(const QByteArray &in, QByteArray &out,
28 const QByteArray &key, bool enc)
29{
30 // 检查密钥合法性(只能是16、24、32字节)
31 Q_ASSERT(key.size() == KEY_SIZE_16B
32 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
33
34 // 根据key大小创建EVP_CIPHER
35 const EVP_CIPHER * cipher = nullptr;
36 if (key.size() == KEY_SIZE_16B)
37 {
38 cipher = EVP_aes_128_ecb();
39 }
40 else if (key.size() == KEY_SIZE_24B)
41 {
42 cipher = EVP_aes_192_ecb();
43 }
44 else
45 {
46 cipher = EVP_aes_256_ecb();
47 }
48
49 // 执行加解密
50 return encrypt(in, out, key, QByteArray(), cipher, enc);
51}
52
53bool EvpAES::cbc_encrypt(const QByteArray &in, QByteArray &out,
54 const QByteArray &key, const QByteArray &ivec, bool enc)
55{
56 // 检查密钥合法性(只能是16、24、32字节)
57 Q_ASSERT(key.size() == KEY_SIZE_16B
58 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
59 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
60
61 // 根据key大小创建EVP_CIPHER
62 const EVP_CIPHER * cipher = nullptr;
63 if (key.size() == KEY_SIZE_16B)
64 {
65 cipher = EVP_aes_128_cbc();
66 }
67 else if (key.size() == KEY_SIZE_24B)
68 {
69 cipher = EVP_aes_192_cbc();
70 }
71 else
72 {
73 cipher = EVP_aes_256_cbc();
74 }
75
76 // 执行加解密
77 return encrypt(in, out, key, ivec, cipher, enc);
78}
79
80bool EvpAES::cfb1_encrypt(const QByteArray &in, QByteArray &out,
81 const QByteArray &key, const QByteArray &ivec, bool enc)
82{
83 // 检查密钥合法性(只能是16、24、32字节)
84 Q_ASSERT(key.size() == KEY_SIZE_16B
85 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
86 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
87
88 // 根据key大小创建EVP_CIPHER
89 const EVP_CIPHER * cipher = nullptr;
90 if (key.size() == KEY_SIZE_16B)
91 {
92 cipher = EVP_aes_128_cfb1();
93 }
94 else if (key.size() == KEY_SIZE_24B)
95 {
96 cipher = EVP_aes_192_cfb1();
97 }
98 else
99 {
100 cipher = EVP_aes_256_cfb1();
101 }
102
103 // 执行加解密
104 return encrypt(in, out, key, ivec, cipher, enc);
105}
106
107bool EvpAES::cfb8_encrypt(const QByteArray &in, QByteArray &out,
108 const QByteArray &key, const QByteArray &ivec, bool enc)
109{
110 // 检查密钥合法性(只能是16、24、32字节)
111 Q_ASSERT(key.size() == KEY_SIZE_16B
112 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
113 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
114
115 // 根据key大小创建EVP_CIPHER
116 const EVP_CIPHER * cipher = nullptr;
117 if (key.size() == KEY_SIZE_16B)
118 {
119 cipher = EVP_aes_128_cfb8();
120 }
121 else if (key.size() == KEY_SIZE_24B)
122 {
123 cipher = EVP_aes_192_cfb8();
124 }
125 else
126 {
127 cipher = EVP_aes_256_cfb8();
128 }
129
130 // 执行加解密
131 return encrypt(in, out, key, ivec, cipher, enc);
132}
133
134bool EvpAES::cfb128_encrypt(const QByteArray &in, QByteArray &out,
135 const QByteArray &key, const QByteArray &ivec, bool enc)
136{
137 // 检查密钥合法性(只能是16、24、32字节)
138 Q_ASSERT(key.size() == KEY_SIZE_16B
139 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
140 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
141
142 // 根据key大小创建EVP_CIPHER
143 const EVP_CIPHER * cipher = nullptr;
144 if (key.size() == KEY_SIZE_16B)
145 {
146 cipher = EVP_aes_128_cfb128();
147 }
148 else if (key.size() == KEY_SIZE_24B)
149 {
150 cipher = EVP_aes_192_cfb128();
151 }
152 else
153 {
154 cipher = EVP_aes_256_cfb128();
155 }
156
157 // 执行加解密
158 return encrypt(in, out, key, ivec, cipher, enc);
159}
160
161bool EvpAES::ofb128_encrypt(const QByteArray &in, QByteArray &out,
162 const QByteArray &key, const QByteArray &ivec, bool enc)
163{
164 // 检查密钥合法性(只能是16、24、32字节)
165 Q_ASSERT(key.size() == KEY_SIZE_16B
166 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
167 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
168
169 // 根据key大小创建EVP_CIPHER
170 const EVP_CIPHER * cipher = nullptr;
171 if (key.size() == KEY_SIZE_16B)
172 {
173 cipher = EVP_aes_128_ofb();
174 }
175 else if (key.size() == KEY_SIZE_24B)
176 {
177 cipher = EVP_aes_192_ofb();
178 }
179 else
180 {
181 cipher = EVP_aes_256_ofb();
182 }
183
184 // 执行加解密
185 return encrypt(in, out, key, ivec, cipher, enc);
186}
187
188bool EvpAES::ctr_encrypt(const QByteArray &in, QByteArray &out,
189 const QByteArray &key, const QByteArray &ivec, bool enc)
190{
191 // 检查密钥合法性(只能是16、24、32字节)
192 Q_ASSERT(key.size() == KEY_SIZE_16B
193 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
194 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
195
196 // 根据key大小创建EVP_CIPHER
197 const EVP_CIPHER * cipher = nullptr;
198 if (key.size() == KEY_SIZE_16B)
199 {
200 cipher = EVP_aes_128_ctr();
201 }
202 else if (key.size() == KEY_SIZE_24B)
203 {
204 cipher = EVP_aes_192_ctr();
205 }
206 else
207 {
208 cipher = EVP_aes_256_ctr();
209 }
210
211 // 执行加解密
212 return encrypt(in, out, key, ivec, cipher, enc);
213}
214
215bool EvpAES::gcm_encrypt(const QByteArray &in, QByteArray &out,
216 const QByteArray &key, const QByteArray &ivec, bool enc)
217{
218 // 检查密钥合法性(只能是16、24、32字节)
219 Q_ASSERT(key.size() == KEY_SIZE_16B
220 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
221 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
222
223 // 根据key大小创建EVP_CIPHER
224 const EVP_CIPHER * cipher = nullptr;
225 if (key.size() == KEY_SIZE_16B)
226 {
227 cipher = EVP_aes_128_gcm();
228 }
229 else if (key.size() == KEY_SIZE_24B)
230 {
231 cipher = EVP_aes_192_gcm();
232 }
233 else
234 {
235 cipher = EVP_aes_256_gcm();
236 }
237
238 // 执行加解密
239 return encrypt(in, out, key, ivec, cipher, enc);
240}
241
242bool EvpAES::xts_encrypt(const QByteArray &in, QByteArray &out,
243 const QByteArray &key, const QByteArray &ivec, bool enc)
244{
245 // 检查密钥合法性(只能是16、32字节)
246 Q_ASSERT(key.size() == KEY_SIZE_16B || key.size() == KEY_SIZE_32B);
247 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
248
249 // 根据key大小创建EVP_CIPHER
250 const EVP_CIPHER * cipher = nullptr;
251 if (key.size() == KEY_SIZE_16B)
252 {
253 cipher = EVP_aes_128_xts();
254 }
255 else
256 {
257 cipher = EVP_aes_256_xts();
258 }
259
260 // 执行加解密
261 return encrypt(in, out, key, ivec, cipher, enc);
262}
263
264bool EvpAES::ocb_encrypt(const QByteArray &in, QByteArray &out,
265 const QByteArray &key, const QByteArray &ivec, bool enc)
266{
267#if OPENSSL_VERSION_NUMBER >= 0x3000000fL
268 #ifndef OPENSSL_NO_OCB
269
270 // 检查密钥合法性(只能是16、24、32字节)
271 Q_ASSERT(key.size() == KEY_SIZE_16B
272 || key.size() == KEY_SIZE_24B || key.size() == KEY_SIZE_32B);
273 Q_ASSERT(ivec.size() == KEY_SIZE_16B); // 初始向量为16字节
274
275 // 根据key大小创建EVP_CIPHER
276 const EVP_CIPHER * cipher = nullptr;
277 if (key.size() == KEY_SIZE_16B)
278 {
279 cipher = EVP_aes_128_ocb();
280 }
281 else if (key.size() == KEY_SIZE_24B)
282 {
283 cipher = EVP_aes_192_ocb();
284 }
285 else
286 {
287 cipher = EVP_aes_256_ocb();
288 }
289
290 // 执行加解密
291 return encrypt(in, out, key, ivec, cipher, enc);
292
293 #endif
294#endif
295 return false;
296}
297
298bool EvpAES::encrypt(const QByteArray &in, QByteArray &out,
299 const QByteArray &key, const QByteArray &ivec,
300 const EVP_CIPHER *cipher, bool enc)
301{
302 if (enc)
303 {
304 // 指定加密算法及key和iv
305 int ret = EVP_EncryptInit_ex(ctx, cipher, NULL,
306 (const unsigned char*)key.data(),
307 (const unsigned char*)ivec.data());
308 if(ret != 1)
309 {
310 return false;
311 }
312
313 // 进行加密操作
314 int mlen = 0;
315 out.resize(in.size() + AES_BLOCK_SIZE);
316 ret = EVP_EncryptUpdate(ctx, (unsigned char*)out.data(), &mlen,
317 (const unsigned char*)in.data(),
318 in.size());
319 if(ret != 1)
320 {
321 return false;
322 }
323
324 // 结束加密操作
325 int flen = 0;
326 ret = EVP_EncryptFinal_ex(ctx, (unsigned char *)out.data() + mlen, &flen);
327 if(ret != 1)
328 {
329 return false;
330 }
331 out.resize(mlen + flen);
332 return true;
333 }
334 else
335 {
336 // 指定解密算法及key和iv
337 int ret = EVP_DecryptInit_ex(ctx, cipher, NULL,
338 (const unsigned char*)key.data(),
339 (const unsigned char*)ivec.data());
340 if(ret != 1)
341 {
342 return false;
343 }
344
345 // 进行解密操作
346 int mlen = 0;
347 out.resize(in.size());
348 ret = EVP_DecryptUpdate(ctx, (unsigned char*)out.data(), &mlen,
349 (const unsigned char*)in.data(), in.size());
350 if(ret != 1)
351 {
352 return false;
353 }
354
355 // 结束解密操作
356 int flen = 0;
357 ret = EVP_DecryptFinal_ex(ctx, (unsigned char *)out.data() + mlen, &flen);
358 if(ret != 1)
359 {
360 return false;
361 }
362 out.resize(mlen + flen);
363 return true;
364 }
365}
366
367//TODO: only install the dependencies libraries(libssl)
368int EvpAES::testSSL()
369{
370#if OPENSSL_VERSION_NUMBER >= 0x3000000fL
371 SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_client_method());
372 if(ssl_ctx)
373 SSL_CTX_free(ssl_ctx);
374#endif
375 return 0;
376}