Skip to content

Commit 75507b0

Browse files
committed
添加封装
1 parent a10c00a commit 75507b0

File tree

7 files changed

+1576
-0
lines changed

7 files changed

+1576
-0
lines changed

QAes/QAes.pri

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
INCLUDEPATH += $$PWD/
2+
SOURCES += \
3+
$$PWD/qaeswrap.cpp \
4+
$$PWD/aes.c
5+
6+
HEADERS += \
7+
$$PWD/qaeswrap.h \
8+
$$PWD/aes.h

QAes/aes.c

+1,098
Large diffs are not rendered by default.

QAes/aes.h

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*********************************************************************
2+
* Filename: aes.h
3+
* Author: Brad Conte (brad AT bradconte.com)
4+
* Copyright:
5+
* Disclaimer: This code is presented "as is" without any guarantees.
6+
* Details: Defines the API for the corresponding AES implementation.
7+
*********************************************************************/
8+
9+
#ifndef AES_H
10+
#define AES_H
11+
12+
/*************************** HEADER FILES ***************************/
13+
#include <stddef.h>
14+
15+
/****************************** MACROS ******************************/
16+
#define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time
17+
18+
/**************************** DATA TYPES ****************************/
19+
typedef unsigned char BYTE; // 8-bit byte
20+
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
21+
22+
/*********************** FUNCTION DECLARATIONS **********************/
23+
///////////////////
24+
// AES
25+
///////////////////
26+
// Key setup must be done before any AES en/de-cryption functions can be used.
27+
// 128 bits = 16 字节
28+
// 192 bits = 24 字节
29+
// 256 bits = 32 字节
30+
void aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits
31+
WORD w[], // Output key schedule to be used later
32+
int keysize); // Bit length of the key, 128, 192, or 256
33+
34+
void aes_encrypt(const BYTE in[], // 16 bytes of plaintext
35+
BYTE out[], // 16 bytes of ciphertext
36+
const WORD key[], // From the key setup
37+
int keysize); // Bit length of the key, 128, 192, or 256
38+
39+
void aes_decrypt(const BYTE in[], // 16 bytes of ciphertext
40+
BYTE out[], // 16 bytes of plaintext
41+
const WORD key[], // From the key setup
42+
int keysize); // Bit length of the key, 128, 192, or 256
43+
44+
///////////////////
45+
// AES - CBC
46+
///////////////////
47+
void aes_encrypt_cbc(const BYTE in[], // Plaintext
48+
size_t in_len, const BYTE * lastBlock, // Must be a multiple of AES_BLOCK_SIZE
49+
BYTE out[], // Ciphertext, same length as plaintext
50+
const WORD key[], // From the key setup
51+
int keysize, // Bit length of the key, 128, 192, or 256
52+
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
53+
54+
void aes_decrypt_cbc(const BYTE in[],
55+
size_t in_len,
56+
BYTE out[],
57+
const WORD key[],
58+
int keysize,
59+
const BYTE iv[]);
60+
61+
//// Only output the CBC-MAC of the input.
62+
//int aes_encrypt_cbc_mac(const BYTE in[], // plaintext
63+
// size_t in_len, // Must be a multiple of AES_BLOCK_SIZE
64+
// BYTE out[], // Output MAC
65+
// const WORD key[], // From the key setup
66+
// int keysize, // Bit length of the key, 128, 192, or 256
67+
// const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
68+
69+
///////////////////
70+
// AES - CTR
71+
///////////////////
72+
//void increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE
73+
// int counter_size); // Bytes of the IV used for counting (low end)
74+
75+
void aes_encrypt_ctr(const BYTE in[], // Plaintext
76+
size_t in_len, // Any byte length
77+
BYTE out[], // Ciphertext, same length as plaintext
78+
const WORD key[], // From the key setup
79+
int keysize, // Bit length of the key, 128, 192, or 256
80+
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
81+
82+
void aes_decrypt_ctr(const BYTE in[], // Ciphertext
83+
size_t in_len, // Any byte length
84+
BYTE out[], // Plaintext, same length as ciphertext
85+
const WORD key[], // From the key setup
86+
int keysize, // Bit length of the key, 128, 192, or 256
87+
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
88+
89+
///////////////////
90+
// AES - CCM
91+
///////////////////
92+
// Returns True if the input parameters do not violate any constraint.
93+
int aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext.
94+
WORD plaintext_len, // IN - Plaintext length.
95+
const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption.
96+
unsigned short associated_data_len, // IN - Associated Data length in bytes.
97+
const BYTE nonce[], // IN - The Nonce to be used for encryption.
98+
unsigned short nonce_len, // IN - Nonce length in bytes.
99+
BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC.
100+
WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len.
101+
WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16.
102+
const BYTE key[], // IN - The AES key for encryption.
103+
int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256.
104+
105+
// Returns True if the input parameters do not violate any constraint.
106+
// Use mac_auth to ensure decryption/validation was preformed correctly.
107+
// If authentication does not succeed, the plaintext is zeroed out. To overwride
108+
// this, call with mac_auth = NULL. The proper proceedure is to decrypt with
109+
// authentication enabled (mac_auth != NULL) and make a second call to that
110+
// ignores authentication explicitly if the first call failes.
111+
int aes_decrypt_ccm(const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC.
112+
WORD ciphertext_len, // IN - Ciphertext length in bytes.
113+
const BYTE assoc[], // IN - The Associated Data, required for authentication.
114+
unsigned short assoc_len, // IN - Associated Data length in bytes.
115+
const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption.
116+
unsigned short nonce_len, // IN - Nonce length in bytes.
117+
BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len.
118+
WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len .
119+
WORD mac_len, // IN - The length of the MAC that was calculated.
120+
int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication.
121+
const BYTE key[], // IN - The AES key for decryption.
122+
int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256.
123+
124+
#endif // AES_H

QAes/qaeswrap.cpp

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#include "qaeswrap.h"
2+
#include <QCryptographicHash>
3+
4+
QAesWrap::QAesWrap(const QByteArray & passwprd,const QByteArray & salt,AesBit bit):mbit(bit)
5+
{
6+
QByteArray data = QCryptographicHash::hash(passwprd,QCryptographicHash::Sha3_256);
7+
aes_key_setup((unsigned char *)data.data(),mpass,mbit);
8+
data = QCryptographicHash::hash(salt,QCryptographicHash::Sha3_256);
9+
memcpy(msalt,data.data(),AES_BLOCK_SIZE);
10+
}
11+
12+
bool QAesWrap::encrypt(const QByteArray & in, QByteArray & out, AesMode mode,PaddingMode pad)
13+
{
14+
out.clear();
15+
switch (mode) {
16+
case AES_CTR:
17+
out.resize(in.size());
18+
aes_encrypt_ctr((unsigned char *)in.data(),in.size(),(unsigned char *)out.data(),mpass,mbit,msalt);
19+
break;
20+
case AES_ECB:
21+
case AES_CBC:
22+
initPadding(in,out,mode,pad);
23+
break;
24+
default:
25+
return false;
26+
}
27+
return true;
28+
}
29+
30+
void QAesWrap::initPadding(const QByteArray & in,QByteArray & out,AesMode mode,PaddingMode pad)
31+
{
32+
int size = in.size();
33+
int last = size % AES_BLOCK_SIZE;
34+
const BYTE * data = (unsigned char *)in.data();
35+
if (last == 0) {
36+
out.resize(size);
37+
if (mode == AES_ECB) {
38+
ecbencrypt(data,size,0,out);
39+
} else {
40+
aes_encrypt_cbc(data,size,0,(unsigned char *)out.data(),mpass,mbit,msalt);
41+
}
42+
return;
43+
}
44+
int blocks = size / AES_BLOCK_SIZE;
45+
46+
BYTE datablocks[AES_BLOCK_SIZE] = {0};
47+
memcpy(datablocks,(data + blocks * AES_BLOCK_SIZE),last);
48+
49+
uchar ch = uchar(AES_BLOCK_SIZE - last);
50+
51+
switch (pad) {
52+
case ANSIX923:
53+
case PKCS7:
54+
{
55+
size = blocks * AES_BLOCK_SIZE;
56+
out.resize((blocks +1) * AES_BLOCK_SIZE);
57+
if (pad == ANSIX923) {
58+
memset(&datablocks[last],0,(ch -1));
59+
datablocks[AES_BLOCK_SIZE -1] = ch;
60+
} else {
61+
memset(&datablocks[last],ch,ch);
62+
}
63+
64+
if (mode == AES_ECB) {
65+
ecbencrypt(data,size,datablocks,out);
66+
} else {
67+
aes_encrypt_cbc(data,size,datablocks,(unsigned char *)out.data(),mpass,mbit,msalt);
68+
}
69+
}
70+
break;
71+
default:
72+
{
73+
if (blocks <= 0) {out = in; return;}
74+
out.resize(size);
75+
size = blocks * AES_BLOCK_SIZE;
76+
if (mode == AES_ECB) {
77+
ecbencrypt(data,size,0,out);
78+
} else {
79+
aes_encrypt_cbc(data,size,0,(unsigned char *)out.data(),mpass,mbit,msalt);
80+
}
81+
for (int i = 0,j = size; i < last; ++i, ++j) {
82+
out[j] = datablocks[i];
83+
}
84+
}
85+
break;
86+
}
87+
}
88+
89+
void QAesWrap::ecbencrypt(const BYTE * in, size_t size, BYTE *blcok, QByteArray & out)
90+
{
91+
BYTE buf_in[AES_BLOCK_SIZE] = {0}, buf_out[AES_BLOCK_SIZE] = {0};
92+
int blocks, idx;
93+
char * data = out.data();
94+
blocks = size / AES_BLOCK_SIZE;
95+
memset(buf_out,0,AES_BLOCK_SIZE);
96+
for (idx = 0; idx < blocks; idx++) {
97+
memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE);
98+
aes_encrypt(buf_in, buf_out, mpass, mbit);
99+
memcpy(&data[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE);
100+
memset(buf_out,0,AES_BLOCK_SIZE);
101+
}
102+
if (blcok) {
103+
memcpy(buf_in, blcok, AES_BLOCK_SIZE);
104+
aes_encrypt(blcok, buf_out, mpass, mbit);
105+
memcpy(&data[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE);
106+
}
107+
}
108+
109+
void QAesWrap::ecbdecrypt(const BYTE *in, size_t size, QByteArray & out)
110+
{
111+
BYTE buf_in[AES_BLOCK_SIZE] = {0}, buf_out[AES_BLOCK_SIZE] = {0};
112+
int blocks, idx;
113+
char * data = out.data();
114+
blocks = size / AES_BLOCK_SIZE;
115+
memset(buf_out,0,AES_BLOCK_SIZE);
116+
for (idx = 0; idx < blocks; idx++) {
117+
memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE);
118+
aes_decrypt(buf_in, buf_out, mpass, mbit);
119+
memcpy(&data[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE);
120+
memset(buf_out,0,AES_BLOCK_SIZE);
121+
}
122+
}
123+
124+
bool QAesWrap::decrypt(const QByteArray & in, QByteArray & out, AesMode mode,PaddingMode pad)
125+
{
126+
out.clear();
127+
int size = in.size();
128+
out.resize(size);
129+
if (mode == AES_CTR) {
130+
aes_encrypt_ctr((unsigned char *)in.data(),size,(unsigned char *)out.data(),mpass,mbit,msalt);
131+
return true;
132+
}
133+
int last = size % AES_BLOCK_SIZE;
134+
int blocks = size / AES_BLOCK_SIZE;
135+
int useSize = blocks * AES_BLOCK_SIZE;
136+
if (blocks == 0 ) {
137+
out = in;
138+
return false;
139+
}
140+
QByteArray tdata;
141+
if (last > 0) {
142+
if(pad == ANSIX923 || pad == PKCS7) {
143+
out.clear();
144+
return false;
145+
}
146+
tdata = in.right(last);
147+
}
148+
149+
150+
switch (mode) {
151+
case AES_ECB:
152+
ecbdecrypt((unsigned char *)in.data(),useSize,out);
153+
break;
154+
case AES_CBC:
155+
aes_decrypt_cbc((unsigned char *)in.data(),useSize,(unsigned char *)out.data(),mpass,mbit,msalt);
156+
break;
157+
default:
158+
return false;
159+
}
160+
if (last > 0) {
161+
for (int i = useSize, j = 0;i < size; ++i,++j) {
162+
out[i] = tdata.at(j);
163+
}
164+
} else {
165+
char ch = out.at(size-1);
166+
if (ch < 16) { //验证是否需要移除。
167+
int removed = 0;
168+
int tsize = size - ch;
169+
bool isPad = true;
170+
if (pad == ANSIX923) {
171+
int mysize = size - 1;
172+
char tch;
173+
for (int i = tsize; i < mysize; ++i) {
174+
tch = out.at(i);
175+
if (tch != char(0x00)) {
176+
isPad = false;
177+
}
178+
}
179+
if (isPad) removed = ch;
180+
}else {
181+
char tch;
182+
for (int i = tsize; i < size; ++i) {
183+
tch = out.at(i);
184+
if (tch != ch) {
185+
isPad = false;
186+
}
187+
}
188+
if (isPad) removed = ch;
189+
}
190+
if (removed > 0) {
191+
out.remove(size - removed,removed);
192+
}
193+
}
194+
}
195+
196+
return true;
197+
}

QAes/qaeswrap.h

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#ifndef QAESWRAP_H
2+
#define QAESWRAP_H
3+
4+
extern "C" {
5+
#include "aes.h"
6+
}
7+
#include <QByteArray>
8+
9+
10+
class QAesWrap
11+
{
12+
public:
13+
enum AesBit {
14+
AES_128 = 128,
15+
AES_192 = 192,
16+
AES_256 = 256
17+
};
18+
enum AesMode {
19+
AES_ECB,
20+
AES_CBC,
21+
AES_CTR
22+
};
23+
enum PaddingMode {
24+
None,
25+
ANSIX923,
26+
PKCS7
27+
};
28+
public:
29+
QAesWrap(const QByteArray & passwprd,const QByteArray & salt,AesBit bit);
30+
31+
bool encrypt(const QByteArray & in, QByteArray & out, AesMode mode,PaddingMode pad = PKCS7);
32+
bool decrypt(const QByteArray & in, QByteArray & out, AesMode mode,PaddingMode pad = PKCS7);
33+
34+
inline QByteArray encrypt(const QByteArray & data,AesMode mode,PaddingMode pad = PKCS7){
35+
QByteArray out;
36+
encrypt(data,out,mode,pad);
37+
return out;
38+
}
39+
40+
inline QByteArray decrypt(const QByteArray & data,AesMode mode,PaddingMode pad = PKCS7){
41+
QByteArray out;
42+
decrypt(data,out,mode,pad);
43+
return out;
44+
}
45+
private:
46+
void ecbencrypt(const BYTE *in, size_t size, BYTE *blcok, QByteArray & out);
47+
void ecbdecrypt(const BYTE *in, size_t size, QByteArray & out);
48+
void initPadding(const QByteArray & in,QByteArray & out,AesMode mode,PaddingMode pad);
49+
private:
50+
AesBit mbit;
51+
WORD mpass[60];
52+
BYTE msalt[AES_BLOCK_SIZE];
53+
};
54+
55+
#endif // QAESWRAP_H

0 commit comments

Comments
 (0)