我有以下代码,基本上是从http://www.cryptopp.com/wiki/AuthenticatedDecryptionFilter
的Crypto ++ wiki中抓取的问题是,输出我得到“明文:abc1230000000077C8E390”而不是我期望的,只是“明文:abc123”
最后的额外数据是什么?
另外两个基于相同代码库的小问题:
这个方法是否可以替代使用pdata的实际随机字节数据,或者因为它的字符串实际上必须像普通文本一样?
我认为adata是以明文形式传输的,所以在存储密文时,我认为iv和adata都是纯文本,而用户只提供密钥(用这些密钥解密密文) 4个元素:密钥(由用户提供),密文(可用),iv(可用)和adata(可用)?
谢谢!
AutoSeededRandomPool prng;
byte key[ AES::DEFAULT_KEYLENGTH ];
prng.GenerateBlock( key, sizeof(key) );
byte iv[ AES::BLOCKSIZE ];
prng.GenerateBlock( iv, sizeof(iv) );
string adata( 16, (char)0x00 );
string cipherText = encryptData("abc123", adata, key, iv);
string plainText = decryptData(cipherText, adata, key, iv);
cout << "plaintext: " << plainText << endl;
//Utilities
string MainWindow::encryptData(string pdata, string adata, const byte *key, const byte *iv) {
const int TAG_SIZE = 16;
string cipher;
try
{
GCM< AES >::Encryption e;
e.SetKeyWithIV( key, AES::DEFAULT_KEYLENGTH, iv, AES::BLOCKSIZE );
AuthenticatedEncryptionFilter ef( e,
new StringSink( cipher ), false, TAG_SIZE
); // AuthenticatedEncryptionFilter
ef.ChannelPut( "AAD", (const byte*)adata.data(), adata.size() );
ef.ChannelMessageEnd("AAD");
ef.ChannelPut( "", (const byte*)pdata.data(), pdata.size() );
ef.ChannelMessageEnd("");
}
catch( CryptoPP::BufferedTransformation::NoChannelSupport& e )
{
cerr << "Caught NoChannelSupport..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::AuthenticatedSymmetricCipher::BadState& e )
{
cerr << "Caught BadState..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::InvalidArgument& e )
{
cerr << "Caught InvalidArgument..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
return(cipher);
}
string MainWindow::decryptData(string cipher, string adata, const byte *key, const byte *iv) {
const int TAG_SIZE = 16;
string radata, rpdata;
try
{
GCM< AES >::Decryption d;
d.SetKeyWithIV( key, AES::DEFAULT_KEYLENGTH, iv, AES::BLOCKSIZE );
string enc = cipher.substr( 0, cipher.length()-TAG_SIZE );
string mac = cipher.substr( cipher.length()-TAG_SIZE );
assert( cipher.size() == enc.size() + mac.size() );
assert( enc.size() == pdata.size() );
assert( TAG_SIZE == mac.size() );
radata = adata;
AuthenticatedDecryptionFilter df( d, NULL,
AuthenticatedDecryptionFilter::MAC_AT_BEGIN |
AuthenticatedDecryptionFilter::THROW_EXCEPTION, TAG_SIZE );
df.ChannelPut( "", (const byte*)mac.data(), mac.size() );
df.ChannelPut( "AAD", (const byte*)adata.data(), adata.size() );
df.ChannelPut( "", (const byte*)enc.data(), enc.size() );
df.ChannelMessageEnd( "AAD" );
df.ChannelMessageEnd( "" );
string retrieved;
size_t n = (size_t)df.MaxRetrievable();
retrieved.resize( n );
if( n > 0 ) { df.Get( (byte*)retrieved.data(), n ); }
rpdata = retrieved;
assert( rpdata == pdata );
}
catch( CryptoPP::InvalidArgument& e )
{
cerr << "Caught InvalidArgument..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::AuthenticatedSymmetricCipher::BadState& e )
{
cerr << "Caught BadState..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::HashVerificationFilter::HashVerificationFailed& e )
{
cerr << "Caught HashVerificationFailed..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
return rpdata;
}
答案 0 :(得分:0)
问题是,我得到的输出&#34;明文:abc1230000000077C8E390&#34;
我的猜测是你重复使用了一个字符串。 Crypto ++将在StringSink
中追加而不是覆盖。所以你得到abc123
,然后你设法以某种方式附加0000000077C8E390
。
以下适用于我。它是您程序的温和修改版本。它使adata
和pdata
全局,重命名它们以避免名称隐藏,并通过pdata
传递消息。
$ ./cryptopp-test.exe
plaintext: Now is the time for all good men to come to the aide of their country
$ ./cryptopp-test.exe wxyz
plaintext: wxyz
因为您使用的是THROW_EXCEPTION
,所以您不需要:
b = df.GetLastResult();
assert( true == b );
我认为adata意图以明文转移......
是。它将类似于IP地址,磁盘扇区或计数器(等等)。
更准确地说,它的数据仅通过身份验证。如果被篡改,将被检测到。
...我是正确的,iv和adata都是纯文本
IV可以是公共或私人参数。
如果是公共参数,则不需要进行身份验证。它有点不直观,但是因为篡改IV会篡改密码的状态,因此解密将失败,就好像你使用了错误的密钥一样。
...用户只提供密钥(用这4个元素解密密文:密钥(由用户提供),密文(可用),iv(可用)和adata(可用)?
pdata
获得机密性和真实性保证;并且adata
仅获得真实性保证。
钥匙和IV是惯例。像往常一样处理它们(或者应该这样做:)。
using CryptoPP::DEFAULT_CHANNEL;
using CryptoPP::AAD_CHANNEL;
string encryptData(const string& pdata, const string& adata, const byte *key, unsigned int ksize, const byte *iv, unsigned int vsize);
string decryptData(const string& cipher, const string& adata, const byte *key, unsigned int ksize, const byte *iv, unsigned int vsize);
string xadata = "172.16.1.10";
string xpdata = "Now is the time for all good men to come to the aide of their country";
static const unsigned int TAG_SIZE = 16;
int main(int argc, char* argv[])
{
(void)argc; (void)argv;
if(argc >= 2)
xpdata = argv[1];
try {
AutoSeededRandomPool prng;
byte key[ AES::DEFAULT_KEYLENGTH ];
prng.GenerateBlock( key, sizeof(key) );
byte iv[ AES::BLOCKSIZE ];
prng.GenerateBlock( iv, sizeof(iv) );
string cipherText = encryptData(xpdata, xadata, key, sizeof(key), iv, sizeof(iv));
string plainText = decryptData(cipherText, xadata, key, sizeof(key), iv, sizeof(iv));
cout << "plaintext: " << plainText << endl;
}
catch(CryptoPP::Exception& ex)
{
cerr << ex.what() << endl;
}
return 0;
}
//Utilities
string encryptData(const string& pdata, const string& adata, const byte *key, unsigned int ksize, const byte *iv, unsigned int vsize) {
string cipher;
GCM< AES >::Encryption e;
e.SetKeyWithIV( key, ksize, iv, vsize );
AuthenticatedEncryptionFilter ef( e,
new StringSink( cipher ), false, TAG_SIZE
); // AuthenticatedEncryptionFilter
ef.ChannelPut(AAD_CHANNEL, (const byte*)adata.data(), adata.size() );
ef.ChannelMessageEnd(AAD_CHANNEL);
ef.ChannelPut(DEFAULT_CHANNEL, (const byte*)pdata.data(), pdata.size() );
ef.ChannelMessageEnd(DEFAULT_CHANNEL);
return(cipher);
}
string decryptData(const string& cipher, const string& adata, const byte *key, unsigned int ksize, const byte *iv, unsigned int vsize) {
string recovered;
GCM< AES >::Decryption d;
d.SetKeyWithIV( key, ksize, iv, vsize );
const string& enc = cipher.substr( 0, cipher.length()-TAG_SIZE );
const string& mac = cipher.substr( cipher.length()-TAG_SIZE );
assert( cipher.size() == enc.size() + mac.size() );
assert( enc.size() == xpdata.size() );
assert( TAG_SIZE == mac.size() );
AuthenticatedDecryptionFilter df( d, new StringSink(recovered),
AuthenticatedDecryptionFilter::MAC_AT_BEGIN |
AuthenticatedDecryptionFilter::THROW_EXCEPTION, TAG_SIZE );
df.ChannelPut(DEFAULT_CHANNEL, (const byte*)mac.data(), mac.size() );
df.ChannelPut(AAD_CHANNEL, (const byte*)adata.data(), adata.size() );
df.ChannelPut(DEFAULT_CHANNEL, (const byte*)enc.data(), enc.size() );
df.ChannelMessageEnd(AAD_CHANNEL);
df.ChannelMessageEnd(DEFAULT_CHANNEL);
assert( recovered == xpdata );
return(recovered);
}