事实上,Crypto++ 教程非常难学。一般来说,要使用 Crypto++ API,您至少需要具备一些密码学的基本知识,我建议您参加Cryptography course。
说了这么多,我来回答你的问题。由于它有点模棱两可,我假设您想使用 CTR 模式解密 AES 密码。作为输入,假设您有一个密码、IV 和密钥(均以 a 中的十六进制表示std::string
)。
#include <iostream>
#include <string>
#include "crypto++/modes.h" // For CTR_Mode
#include "crypto++/filters.h" //For StringSource
#include "crypto++/aes.h" // For AES
#include "crypto++/hex.h" // For HexDecoder
int main(int argc, char* argv[]) {
// Our input:
// Note: the input was previously generated by the same cipher
std::string iv_string = "37C6D22FADE22B2D924598BEE2455EFC";
std::string cipher_string = "221DF9130F0E05E7E87C89EE6A";
std::string key_string = "7D9BB722DA2DC8674E08C3D44AAE976F";
std::cout << "Cipher text: " << cipher_string << std::endl;
std::cout << "Key: " << key_string << std::endl;
std::cout << "IV: " << iv_string << std::endl;
// 1. Decode iv:
// At the moment our input is encoded in string format...
// we need it in raw hex:
byte iv[CryptoPP::AES::BLOCKSIZE] = {};
// this decoder would transform our std::string into raw hex:
CryptoPP::HexDecoder decoder;
decoder.Put((byte*)iv_string.data(), iv_string.size());
decoder.MessageEnd();
decoder.Get(iv, sizeof(iv));
// 2. Decode cipher:
// Next, we do a similar trick for cipher, only here we would leave raw hex
// in a std::string.data(), since it is convenient for us to pass this
// std::string to the decryptor mechanism:
std::string cipher_raw;
{
CryptoPP::HexDecoder decoder;
decoder.Put((byte*)cipher_string.data(), cipher_string.size());
decoder.MessageEnd();
long long size = decoder.MaxRetrievable();
cipher_raw.resize(size);
decoder.Get((byte*)cipher_raw.data(), cipher_raw.size());
// If we print this string it's completely rubbish:
// std::cout << "Raw cipher: " << cipher_raw << std::endl;
}
// 3. Decode the key:
// And finally the same for the key:
byte key[CryptoPP::AES::DEFAULT_KEYLENGTH];
{
CryptoPP::HexDecoder decoder;
decoder.Put((byte*)key_string.data(), key_string.size());
decoder.MessageEnd();
decoder.Get(key, sizeof(key));
}
// 4. Decrypt:
std::string decrypted_text;
try {
CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption d;
d.SetKeyWithIV(key, sizeof(key), iv);
CryptoPP::StringSource ss(
cipher_raw,
true,
new CryptoPP::StreamTransformationFilter(
d,
new CryptoPP::StringSink(decrypted_text)
) // StreamTransformationFilter
); // StringSource
std::cout << "Decrypted text: " << decrypted_text << std::endl;
}
catch( CryptoPP::Exception& e ) {
std::cerr << e.what() << std::endl;
exit(1);
}
return 0;
}
我使用 Crypto++562 在 Ubutunu 14.04 上编译它:
g++ -Wall -std=c++0x -o prog practicalAES.cpp -lcryptopp
如果我运行程序,我会得到以下输出:
Cipher text: 221DF9130F0E05E7E87C89EE6A
Key: 7D9BB722DA2DC8674E08C3D44AAE976F
IV: 37C6D22FADE22B2D924598BEE2455EFC
Decrypted text: CTR Mode Test
它在这里并不真正可见,但 Key 和 IV 具有相同的长度 - 16 个字节(或 128 位)。这是块大小,所以这个密码是 AES-128。由于是CTR方式,所以不加padding,密文和明文的字节数相同。
另请注意,60% 的代码涉及将字符串解码为十六进制,而解密本身只是最后一步(因此,如果您的输入数据是原始十六进制,则不需要解码)。