我指的是CCM Mode上Crypto ++ wiki上的示例代码。我为测试目的做了一些修改,现在它正在抛出:
terminate called after throwing an instance of 'HashVerificationFilter::HashVerificationFailed'
what(): HashVerificationFilter: message hash or MAC not valid
Aborted (core dumped)
我见过'message hash or MAC not valid' exception after decryption。但我想传递字节数组而不是字符串,所以我认为我必须使用sizeof()
运算符而不是size()
。代码如下。
当传递密钥和iv时,sizeof
函数将其大小设为8而不是16字节。
错误是因为AuthenticatedDecryptionFilter::DEFAULT_FLAGS
吗?
以下是代码:
#include <iostream>
#include <cstdio>
//#include "libcryptoWrapperGCM.h"
using std::cout;
using std::endl;
using std::cerr;
#include <string>
#include <stdint.h>
using std::string;
#include "hex.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
#include "osrng.h"
using CryptoPP::AutoSeededRandomPool;
#include "cryptlib.h"
using CryptoPP::BufferedTransformation;
using CryptoPP::AuthenticatedSymmetricCipher;
#include "filters.h"
using CryptoPP::Redirector;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
#include "aes.h"
using CryptoPP::AES;
#include "gcm.h"
using CryptoPP::GCM;
#include "assert.h"
void GCM_Encode(byte key[], byte iv[], string pdata, string cipher, const int TAG_SIZE)
{
// Encrypted, with Tag
string encoded;
cout << "key size= " << sizeof(key) << endl;
cout << "IV size= " << sizeof(iv) << endl;
/*********************************\
\*********************************/
try
{
GCM< AES >::Encryption e;
e.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
StringSource ss1( pdata, true,
new AuthenticatedEncryptionFilter( e,
new StringSink( cipher ), false, TAG_SIZE
) // AuthenticatedEncryptionFilter
); // StringSource
cout << "Encoded value: " << cipher << endl;
}
catch( CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
}
/*********************************\
\*********************************/
void GCM_Decode(byte key[], byte iv[], string cipher, string rpdata, const int TAG_SIZE)
{
try
{
GCM< AES >::Decryption d;
d.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
AuthenticatedDecryptionFilter df( d,
new StringSink( rpdata ),
AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE
); // AuthenticatedDecryptionFilter
// The StringSource dtor will be called immediately
// after construction below. This will cause the
// destruction of objects it owns. To stop the
// behavior so we can get the decoding result from
// the DecryptionFilter, we must use a redirector
// or manually Put(...) into the filter without
// using a StringSource.
StringSource ss2( cipher, true,
new Redirector( df /*, PASS_EVERYTHING */ )
); // StringSource
// If the object does not throw, here's the only
// opportunity to check the data's integrity
if( true == df.GetLastResult() ) {
cout << "recovered text: " << rpdata << endl;
}
}
catch( CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
}
int main()
{
byte key[]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
byte iv[] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f};
string pdata = "Authenticated Encryption";
const int TAG_SIZE = 12;
string rpdata, cipher;
//void GCM_Encode(byte key[], byte iv[], string pdata, string cipher, const int TAG_SIZE)
GCM_Encode( key, iv, pdata, cipher, TAG_SIZE);
cout << "======INT MAIN======" << endl;
cout << "Encryption complete" << endl;
cout << "cipher= " << cipher << endl;
//void GCM_Decode(byte key[], byte iv[], string cipher, string rpdata, const int TAG_SIZE)
GCM_Decode( key, iv, cipher, rpdata, TAG_SIZE);
cout << "Decryption complete" << endl;
cout << "rpdata= " << rpdata << endl;
return 0;
}
GDB输出是,
Encryption complete
cipher=
HashVerificationFilter: message hash or MAC not valid
[Inferior 1 (process 16632) exited with code 01]
编译命令
g++ -g3 -O3 -fPIC GCM_Test2.cpp -o GCMTest3 -lcryptopp -pthread -lrt -lc
包含使用添加的路径,
export CPLUS_INCLUDE_PATH=/usr/local/include/cryptopp
locate raise.c
答案 0 :(得分:1)
问题是GCM_Encode这两个函数都解释了密钥和iv的错误大小。
cout << "sizeof(key)= " << sizeof(key) << endl;
cout << "sizeof(iv)= " << sizeof(iv) << endl;
是8而不是16.所以想法是将它转换为字符串并使用.size()
获取其大小
std::string key1( reinterpret_cast<char const*>(key), sizeof(key) )
std::string iv1( reinterpret_cast<char const*>(iv), sizeof(iv) )
但请记住向SetKeyWithIV
函数提供原始字节数组,因为它不接受字符串作为其参数。
e.SetKeyWithIV( key, key1.size(), iv, iv1.size() )