一. 下载Crypto++ Library
Crypto++ Library的官方网:http://www.cryptopp.com/
二. 建立自己使用的Crypto++ Library
由于从官方网下载的Crypto++库是开源的,只有源文件和几个可以生成lib、dll的工程,以及一个使用的例子工程,因此希望生成自己建的工程能使用的SDK。
1.编译链接生成cryptlib.lib
打开cryptest.sln,分别在Debug模式和Release模式下编译链接cryptlib工程,成功后会在cryptopp54\Win32\output\debug和cryptopp54\Win32\output\release下生成cryptlib.lib文件。作者当时用的是Crypto++ 5.62版本。
Build时方法是,右击Solution Explorer中的cryptlib工程,单击build。第一次时它会报错,没关系,按这样再build一次,就可以build成功了。
2. 建立Crypto++ SDK
在C:\Program Files\中新建文件夹,取名“CryptoPP”,里面新建文件夹“include”、“lib”,在“lib”中新建文件夹“debug”、“release”。将Crypto++库中的所有头文件复制到“include”文件夹中,再将上面生成的两个cryptlib.lib分别复制到“debug”和“release”中。
三. 基于模式的AES加解密
1、20/13中新建Win32 Console Application工程,建立空的工程。完成后新建文件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 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
#include "stdafx.h" #include <aes.h> #include <Hex.h> // StreamTransformationFilter #include <modes.h> // CFB_Mode #include <iostream> // std:cerr #include <sstream> // std::stringstream #include <string> using namespace std; using namespace CryptoPP; #pragma comment( lib, "cryptlib.lib" ) std::string ECB_AESEncryptStr(std::string sKey, const char *plainText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH); ECB_Mode_ExternalCipher::Encryption ecbEncryption(aesEncryption); StreamTransformationFilter ecbEncryptor(ecbEncryption, new HexEncoder(new StringSink(outstr))); ecbEncryptor.Put((byte *)plainText, strlen(plainText)); ecbEncryptor.MessageEnd(); return outstr; } std::string ECB_AESDecryptStr(std::string sKey, const char *cipherText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); ECB_Mode<AES >::Decryption ecbDecryption((byte *)key, AES::MAX_KEYLENGTH); HexDecoder decryptor(new StreamTransformationFilter(ecbDecryption, new StringSink(outstr))); decryptor.Put((byte *)cipherText, strlen(cipherText)); decryptor.MessageEnd(); return outstr; } std::string CBC_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH); CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv); StreamTransformationFilter cbcEncryptor(cbcEncryption, new HexEncoder(new StringSink(outstr))); cbcEncryptor.Put((byte *)plainText, strlen(plainText)); cbcEncryptor.MessageEnd(); return outstr; } std::string CBC_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); CBC_Mode<AES >::Decryption cbcDecryption((byte *)key, AES::MAX_KEYLENGTH, iv); HexDecoder decryptor(new StreamTransformationFilter(cbcDecryption, new StringSink(outstr))); decryptor.Put((byte *)cipherText, strlen(cipherText)); decryptor.MessageEnd(); return outstr; } std::string CBC_CTS_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH); CBC_CTS_Mode_ExternalCipher::Encryption cbcctsEncryption(aesEncryption, iv); StreamTransformationFilter cbcctsEncryptor(cbcctsEncryption, new HexEncoder(new StringSink(outstr))); cbcctsEncryptor.Put((byte *)plainText, strlen(plainText)); cbcctsEncryptor.MessageEnd(); return outstr; } std::string CBC_CTS_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); CBC_CTS_Mode<AES >::Decryption cbcctsDecryption((byte *)key, AES::MAX_KEYLENGTH, iv); HexDecoder decryptor(new StreamTransformationFilter(cbcctsDecryption, new StringSink(outstr))); decryptor.Put((byte *)cipherText, strlen(cipherText)); decryptor.MessageEnd(); return outstr; } std::string CFB_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH); CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv); StreamTransformationFilter cfbEncryptor(cfbEncryption, new HexEncoder(new StringSink(outstr))); cfbEncryptor.Put((byte *)plainText, strlen(plainText)); cfbEncryptor.MessageEnd(); return outstr; } std::string CFB_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); CFB_Mode<AES >::Decryption cfbDecryption((byte *)key, AES::MAX_KEYLENGTH, iv); HexDecoder decryptor(new StreamTransformationFilter(cfbDecryption, new StringSink(outstr))); decryptor.Put((byte *)cipherText, strlen(cipherText)); decryptor.MessageEnd(); return outstr; } std::string OFB_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH); OFB_Mode_ExternalCipher::Encryption ofbEncryption(aesEncryption, iv); StreamTransformationFilter ofbEncryptor(ofbEncryption, new HexEncoder(new StringSink(outstr))); ofbEncryptor.Put((byte *)plainText, strlen(plainText)); ofbEncryptor.MessageEnd(); return outstr; } std::string OFB_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); OFB_Mode<AES >::Decryption ofbDecryption((byte *)key, AES::MAX_KEYLENGTH, iv); HexDecoder decryptor(new StreamTransformationFilter(ofbDecryption, new StringSink(outstr))); decryptor.Put((byte *)cipherText, strlen(cipherText)); decryptor.MessageEnd(); return outstr; } std::string CTR_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH); CTR_Mode_ExternalCipher::Encryption ctrEncryption(aesEncryption, iv); StreamTransformationFilter ctrEncryptor(ctrEncryption, new HexEncoder(new StringSink(outstr))); ctrEncryptor.Put((byte *)plainText, strlen(plainText)); ctrEncryptor.MessageEnd(); return outstr; } std::string CTR_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText) { std::string outstr; //填key SecByteBlock key(AES::MAX_KEYLENGTH); memset(key,0x30,key.size() ); sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH); //填iv byte iv[AES::BLOCKSIZE]; memset(iv,0x30,AES::BLOCKSIZE); sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE); CTR_Mode<AES >::Decryption ctrDecryption((byte *)key, AES::MAX_KEYLENGTH, iv); HexDecoder decryptor(new StreamTransformationFilter(ctrDecryption, new StringSink(outstr))); decryptor.Put((byte *)cipherText, strlen(cipherText)); decryptor.MessageEnd(); return outstr; } int _tmain(int argc, _TCHAR* argv[]) { string plainText = "This Program shows how to use ECB, CBC, CBC_CTS, CFB, OFB and CTR mode of AES in Crypto++."; string aesKey = "0123456789ABCDEF0123456789ABCDEF";//256bits, also can be 128 bits or 192bits string aesIV = "ABCDEF0123456789";//128 bits string ECB_EncryptedText,ECB_DecryptedText, CBC_EncryptedText,CBC_DecryptedText, CBC_CTS_EncryptedText,CBC_CTS_DecryptedText, CFB_EncryptedText,CFB_DecryptedText, OFB_EncryptedText,OFB_DecryptedText, CTR_EncryptedText,CTR_DecryptedText; //ECB ECB_EncryptedText = ECB_AESEncryptStr(aesKey, plainText.c_str());//ECB加密 ECB_DecryptedText = ECB_AESDecryptStr(aesKey,ECB_EncryptedText.c_str());//ECB解密 //CBC CBC_EncryptedText = CBC_AESEncryptStr(aesKey, aesIV, plainText.c_str());//CBC加密 CBC_DecryptedText = CBC_AESDecryptStr(aesKey, aesIV, CBC_EncryptedText.c_str());//CBC解密 //CBC_CTS CBC_CTS_EncryptedText = CBC_CTS_AESEncryptStr(aesKey, aesIV, plainText.c_str());//CBC_CTS加密 CBC_CTS_DecryptedText = CBC_CTS_AESDecryptStr(aesKey, aesIV, CBC_CTS_EncryptedText.c_str());//CBC_CTS解密 //CFB CFB_EncryptedText = CFB_AESEncryptStr(aesKey, aesIV, plainText.c_str());//CFB加密 CFB_DecryptedText = CFB_AESDecryptStr(aesKey, aesIV, CFB_EncryptedText.c_str());//CFB解密 //OFB OFB_EncryptedText = OFB_AESEncryptStr(aesKey, aesIV, plainText.c_str());//OFB加密 OFB_DecryptedText = OFB_AESDecryptStr(aesKey, aesIV, OFB_EncryptedText.c_str());//OFB解密 //CTR CTR_EncryptedText = CTR_AESEncryptStr(aesKey, aesIV, plainText.c_str());//CTR加密 CTR_DecryptedText = CTR_AESDecryptStr(aesKey, aesIV, CTR_EncryptedText.c_str());//CTR解密 cout << "Crypto++ AES-256 加密测试"<< endl; cout << "分别使用ECB,CBC, CBC_CTR,CFB,OFB和CTR模式"<< endl; cout << "加密用密钥:" << aesKey << endl; cout << "密钥长度:" << AES::MAX_KEYLENGTH*8 <<"bits" << endl; cout << "IV:" << aesIV << endl; cout << endl; cout << "ECB测试"<< endl; cout << "原文:" << plainText << endl; cout << "密文:" << ECB_EncryptedText << endl; cout << "恢复明文:" << ECB_DecryptedText << endl << endl; cout << "CBC测试"<< endl; cout << "原文:" << plainText << endl; cout << "密文:" << CBC_EncryptedText << endl; cout << "恢复明文:" << CBC_DecryptedText << endl << endl; cout << "CBC_CTS测试"<< endl; cout << "原文:" << plainText << endl; cout << "密文:" << CBC_CTS_EncryptedText << endl; cout << "恢复明文:" << CBC_CTS_DecryptedText << endl << endl; cout << "CFB测试"<< endl; cout << "原文:" << plainText << endl; cout << "密文:" << CFB_EncryptedText << endl; cout << "恢复明文:" << CFB_DecryptedText << endl << endl; cout << "OFB测试"<< endl; cout << "原文:" << plainText << endl; cout << "密文:" << OFB_EncryptedText << endl; cout << "恢复明文:" << OFB_DecryptedText << endl << endl; cout << "CTR测试"<< endl; cout << "原文:" << plainText << endl; cout << "密文:" << CTR_EncryptedText << endl; cout << "恢复明文:" << CTR_DecryptedText << endl << endl; getchar(); return 0; } |
2 2、设置工程属性
选择工程属性(Alt + F7):
(1)“Configuration Properties”→“C/C++” →“General”,右边的“Additional Include Directories”设置为上面建好的Crypto++ SDK的 Include文件夹,“C:\Program Files\CyptoPP\include”;
(2) “Configuration Properties”→“Linker” →“General”,右边的“Additional Library Directories”设置为上面建好的Crypto++ SDK的Lib\Debug文件夹,“C:\Program Files\CyptoPP\lib\debug”(Release模式下对应着Release文件夹);
(3) “Configuration Properties”→“C/C++” →“Code Generation”,右边的“Runtime Library”设置为“Multi-threaded Debug (/MTd)”(Release模式下对应着“Multi-threaded (/MT)”)
3、运行程序(Ctrl + F5)
输出结果如下:
挺好的,祝你快乐