-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAES.h
174 lines (146 loc) · 5.18 KB
/
AES.h
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
// AES.h
//
// AES (Advanced Encryption Standard) for C++ strings using CommomCrypto library.
// Made by GrimReaper31, 15/01/2024.
//
#ifndef AESCryptor_h
#define AESCryptor_h
#include <CommonCrypto/CommonCrypto.h>
#include <string>
#include <vector>
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif
class AESCryptor {
public:
AESCryptor(const std::string& key, const std::string& iv) {
if (key.size() < kCCKeySizeAES256) {
throw std::invalid_argument("key.size() < 32 bytes");
}
if (iv.size() < kCCBlockSizeAES128) {
throw std::invalid_argument("iv.size() < 16 bytes");
}
std::copy_n(key.begin(), kCCKeySizeAES256, aes_key);
std::copy_n(iv.begin(), kCCBlockSizeAES128, aes_iv);
}
template <size_t KeySize, size_t IVSize>
constexpr AESCryptor(const char (&key)[KeySize], const char (&iv)[IVSize]) {
static_assert(KeySize >= kCCKeySizeAES256 + 1, "key.size() < 32 bytes");
static_assert(IVSize >= kCCBlockSizeAES128 + 1, "iv.size() < 16 bytes");
std::copy_n(key, kCCKeySizeAES256, aes_key);
std::copy_n(iv, kCCBlockSizeAES128, aes_iv);
}
std::string DecryptHex(const std::string& hexCiphertext) const noexcept {
std::string binaryCiphertext = FromHexString(hexCiphertext);
if (binaryCiphertext.empty()) {
return "";
}
return Decrypt(binaryCiphertext);
}
std::string EncryptHex(const std::string& plaintext) const noexcept {
std::string ciphertext = Encrypt(plaintext);
if (ciphertext.empty()) {
return "";
}
return ToHexString(ciphertext);
}
#ifdef __OBJC__
NSString* NSDecryptHex(const std::string& hexCiphertext) const noexcept {
std::string decryptedText = DecryptHex(hexCiphertext);
if (decryptedText.empty()) {
return nil;
}
return ToNSString(decryptedText);
}
NSString* NSEncryptHex(const std::string& plaintext) const noexcept {
std::string ciphertextHex = EncryptHex(plaintext);
if (ciphertextHex.empty()) {
return nil;
}
return ToNSString(ciphertextHex);
}
#endif
private:
std::string Encrypt(const std::string& plaintext) const noexcept {
std::vector<unsigned char> data(plaintext.begin(), plaintext.end());
size_t dataOutAvailable = data.size() + kCCBlockSizeAES128;
std::vector<unsigned char> dataOut(dataOutAvailable);
size_t dataOutMoved;
CCCryptorStatus status = CCCrypt(
kCCEncrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding,
aes_key,
kCCKeySizeAES256,
aes_iv,
data.data(),
data.size(),
dataOut.data(),
dataOutAvailable,
&dataOutMoved
);
if (status != kCCSuccess) {
return "";
}
return std::string(reinterpret_cast<char*>(dataOut.data()), dataOutMoved);
}
std::string Decrypt(const std::string& ciphertext) const noexcept {
std::vector<unsigned char> data(ciphertext.begin(), ciphertext.end());
size_t dataOutAvailable = data.size();
std::vector<unsigned char> dataOut(dataOutAvailable);
size_t dataOutMoved;
CCCryptorStatus status = CCCrypt(
kCCDecrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding,
aes_key,
kCCKeySizeAES256,
aes_iv,
data.data(),
data.size(),
dataOut.data(),
dataOutAvailable,
&dataOutMoved
);
if (status != kCCSuccess) {
return "";
}
return std::string(reinterpret_cast<char*>(dataOut.data()), dataOutMoved);
}
std::string ToHexString(const std::string& input) const noexcept {
static const char hexDigits[] = "0123456789ABCDEF";
std::string output;
output.reserve(input.length() * 2);
for (unsigned char c : input) {
output.push_back(hexDigits[c >> 4]);
output.push_back(hexDigits[c & 0x0F]);
}
return output;
}
std::string FromHexString(const std::string& hex) const noexcept {
if (hex.length() % 2 != 0) {
return "";
}
std::string output;
output.reserve(hex.length() / 2);
for (size_t i = 0; i < hex.length(); i += 2) {
std::string byteString = hex.substr(i, 2);
try {
char byte = static_cast<char>(std::stoul(byteString, nullptr, 16));
output.push_back(byte);
} catch (...) {
return "";
}
}
return output;
}
#ifdef __OBJC__
NSString* ToNSString(const std::string& input) const noexcept {
return [NSString stringWithUTF8String:input.c_str()];
}
#endif
private:
unsigned char aes_key[kCCKeySizeAES256];
unsigned char aes_iv[kCCBlockSizeAES128];
};
#endif /* AESCryptor_h */