這陣子寫了一些數據加密的小程序,對比了好幾種算法後,選擇了AES,高級加密標准(英語:Advanced Encryption Standard,縮寫:AES),聽這名字就很厲害的樣子
估計會搜索到這文章的,對AES算法已經有了些基本了解了吧,下面先簡單介紹一下AES加密算法吧
(1)AES在密碼學中又稱Rijndael加密法,是美國聯邦政府采用的一種區塊加密標准。2006年,高級加密標准已然成為對稱密鑰加密中最流行的算法之一。
(2)AES加密數據塊分組長度必須為128比特,密鑰長度可以是128比特、192比特、256比特中的任意一個。(8比特 == 1字節)
(3)在CBC、CFB、OFB、CTR模式下除了密鑰外,還需要一個初始化向IV。(ECB模式不用IV)
我使用的是Crypto++庫,開發者是Wei Dai,使用C++寫的加密庫,實現了非常多的加密算法,基本能滿足我們的加密需求,使用起來也很簡單方便,這是官方網站http://www.cryptopp.com/
寫這文章目的不是介紹AES算法,只是想給一個小例子讓大家參考一下而已,避免大家在查了大半天加密算法,看了老久AES原理,可就是就不知道怎麼使用
(基本加解密過程是stackoverflow的一個小demo,我將它修改一下,實現了一個在兩個程序之間,以文件做為介質的加解密的過程)
這裡選的是CBC模式(其它模式調用也一樣)
1、程序一:加密
#include#include #include #include #include #include #include using namespace std; byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE]; void initKV() { memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH ); memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE ); // 或者也可以 /* char tmpK[] = 1234567890123456; char tmpIV[] = 1234567890123456; for (int j = 0; j < CryptoPP::AES::DEFAULT_KEYLENGTH; ++j) { key[j] = tmpK[j]; } for (int i = 0; i < CryptoPP::AES::BLOCKSIZE; ++i) { iv[i] = tmpIV[i]; } */ } string encrypt(string plainText) { string cipherText; // CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, iv ); CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( cipherText )); stfEncryptor.Put( reinterpret_cast ( plainText.c_str() ), plainText.length() + 1 ); stfEncryptor.MessageEnd(); string cipherTextHex; for( int i = 0; i < cipherText.size(); i++ ) { char ch[3] = {0}; sprintf(ch, %02x, static_cast (cipherText[i])); cipherTextHex += ch; } return cipherTextHex; } void writeCipher(string output) { ofstream out(/tmp/cipher.data); out.write(output.c_str(), output.length()); out.close(); cout<
程序二:解密
#include#include #include #include #include #include #include using namespace std; byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE]; void initKV() { memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH ); memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE ); // 或者也可以 /* char tmpK[] = 1234567890123456; char tmpIV[] = 1234567890123456; for (int j = 0; j < CryptoPP::AES::DEFAULT_KEYLENGTH; ++j) { key[j] = tmpK[j]; } for (int i = 0; i < CryptoPP::AES::BLOCKSIZE; ++i) { iv[i] = tmpIV[i]; } */ } string decrypt(string cipherTextHex) { string cipherText; string decryptedText; int i = 0; while(true) { char c; int x; stringstream ss; ss< >x; c = (char)x; cipherText += c; if(i >= cipherTextHex.length() - 2)break; i += 2; } // CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv ); CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedText )); stfDecryptor.Put( reinterpret_cast ( cipherText.c_str() ), cipherText.size()); stfDecryptor.MessageEnd(); return decryptedText; } string readCipher() { ifstream in(/tmp/cipher.data); string line; string decryptedText; while(getline(in, line)) { if(line.length() > 1) { decryptedText += decrypt(line) + ; } line.clear(); } cout<
安裝cryptopp: sudo apt-get install libcrypto++-dev 編譯:g++ main.cpp -o main -lcryptopp