我正在试图弄清楚如何使用AES解密密码块。我正在使用crypto ++库 - 或至少尝试使用该库。但我绝对无处可去。我假设运行这个解密算法只有几行代码,但我无法弄明白。这就是我写的。现在开始笑:
#include <stdio.h>
#include <cstdlib>
#include <rijndael.h>
#include <sha.h>
using namespace std;
int main()
{
// Decryption
CTR_Mode< AES >::Decryption decryptor;
decryptor.SetKeyWithIV( cbcKey, AES::DEFAULT_KEYLENGTH, cbcCipher );
}
任何人都可以给我一个简短的教程,说明如何使用crypto ++“解密”给定解密密钥的16字节密码块?他们的文档比你上面看到的密文(至少对我而言)更加神秘,而且我通过搜索找不到任何帮助。非常感谢你。
答案 0 :(得分:1)
crypto ++库网页上的常见问题解答包含指向“教程”的指针,请阅读over there。
答案 1 :(得分:1)
任何人都可以给我一个简短的教程,说明如何使用crypto ++“解密”给定解密密钥的16字节密码块?
这来自Crypto ++ wiki。它提供了CTR mode example。
AutoSeededRandomPool prng;
SecByteBlock key(AES::DEFAULT_KEYLENGTH);
prng.GenerateBlock( key, key.size() );
byte ctr[ AES::BLOCKSIZE ];
prng.GenerateBlock( ctr, sizeof(ctr) );
string plain = "CTR Mode Test";
string cipher, encoded, recovered;
/*********************************\
\*********************************/
try
{
cout << "plain text: " << plain << endl;
CTR_Mode< AES >::Encryption e;
e.SetKeyWithIV( key, key.size(), ctr );
// The StreamTransformationFilter adds padding
// as required. ECB and CBC Mode must be padded
// to the block size of the cipher. CTR does not.
StringSource ss1( plain, true,
new StreamTransformationFilter( e,
new StringSink( cipher )
) // StreamTransformationFilter
); // StringSource
}
catch( CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
/*********************************\
\*********************************/
// Pretty print cipher text
StringSource ss2( cipher, true,
new HexEncoder(
new StringSink( encoded )
) // HexEncoder
); // StringSource
cout << "cipher text: " << encoded << endl;
/*********************************\
\*********************************/
try
{
CTR_Mode< AES >::Decryption d;
d.SetKeyWithIV( key, key.size(), ctr );
// The StreamTransformationFilter removes
// padding as required.
StringSource ss3( cipher, true,
new StreamTransformationFilter( d,
new StringSink( recovered )
) // StreamTransformationFilter
); // StringSource
cout << "recovered text: " << recovered << endl;
}
catch( CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
以下是运行示例程序的结果:
$ ./crytpopp-test.exe
key: F534FC7F0565A8CF1629F01DB31AE3CA
counter: A4D16CBC010DACAA2E54FA676B57A345
plain text: CTR Mode Test
cipher text: 12455EDB41020E6D751F207EE6
recovered text: CTR Mode Test
答案 2 :(得分:0)
确实,Crypto ++教程非常难以理解。一般来说,为了使用Crypto ++ API,你需要至少掌握一些关于密码学的基础知识,我建议this Cryptography course。
话虽如此,让我解决你的问题。由于它有点含糊不清,我认为你想使用CTR模式解密AES密码。作为输入,让我们说你有一个密码,IV和密钥(所有都以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模式,因此不添加填充,密码和纯文本都具有相同的字节数。
另请注意,60%的代码涉及将字符串解码为十六进制,而解密本身只是最后一步(因此,如果您的输入数据是原始十六进制,则不需要解码)。
答案 3 :(得分:0)
Crypto ++的教程主要关注过滤器和源和接收器的使用,在我看来,这些过滤器和接收器都很复杂。在您的情况下,代码实际上非常简单:
CTR_Mode< AES >::Decryption decryptor;
decryptor.SetKeyWithIV( cbcKey, AES::DEFAULT_KEYLENGTH, cbcCipher );
decryptor.ProcessData(output, input, size);
// Decrypt another piece of data with the same key
decryptor.Resynchronize(new_iv, new_iv_length);
decryptor.ProcessData(new_output, new_input, size);