在标题中,我在此声明
之间的cryptopp库中寻找差异CBC_Mode<AES>::Decryption
cbcDecryption.SetKeyWithIV(key, AES::DEFAULT_KEYLENGTH, iv);
和这一个:
AES::Decryption aesDecryption(key, AES::DEFAULT_KEYLENGTH);
CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );
此外,我无法理解为什么:
AES::Decryption aesDecryption(key, AES::DEFAULT_KEYLENGTH);
CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );
StreamTransformationFilter stfDecryptor(
cbcDecryption,
new StringSink( recoveredtext )
);
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( ciphertext.c_str() ), ciphertext.size() );
stfDecryptor.MessageEnd();
使用模板化模式时一切正常我在运行时期间出现此错误:
AES128CBC: /usr/local/include/cryptopp/misc.h:304: void CryptoPP::memcpy_s(void*, size_t, const void*, size_t): Assertion `dest != __null' failed.
Aborted (core dumped)
不应该是一样的吗?
我查看了this,但我并不了解差异并通过网络搜索我无法找到问题的答案。
答案 0 :(得分:2)
模板化模式对象和外部密码对象之间有什么区别?
*_ExternalCiphers
的解释在modes.h
中给出,它显示在CipherModeDocumentation Class Reference
的网络上。它不容易找到,我只知道它,因为我与消息来源密切合作。
以下是文字:
从这个派生的每个类[CipherModeDocumentation]定义了两种类型,加密和解密,两者都实现了SymmetricCipher接口。对于每种模式,有两个类,其中一个是模板类,另一个的名称以“_ExternalCipher”结尾。
“外部密码”模式对象保存对底层块密码的引用,而不是保存它的实例。必须将引用传递给构造函数。对于“密码持有者”类,CIPHER模板参数应该是从BlockCipherDocumentation派生的类,例如DES或AES。
所以区别在于操作模式如何与密码相关联 - 字面意思是外部与内部。
外部 - 以下是两个不同的对象。第一个是对称密码,第二个是操作模式:
AES::Encryption aes(key, ...);
CBC_Mode_ExternalCipher::Encryption cbc(aes, ...);
内部 - 以下是单个对象。操作模式“具有”通过模板实例化的对称密码:
CBC_Mode<AES>::Encryption enc(key, ...);
使用模板化模式时一切正常我在运行时遇到此错误...
好的,这是一个不同的问题。让我们看看如何使用它:
$ grep -IR "CBC_Mode_ExternalCipher::Decryption" *
fipstest.cpp: KnownAnswerTest(CBC_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), ...);
validat1.cpp: CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
validat1.cpp: CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
validat1.cpp: CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
validat1.cpp: CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
您可以找到validat1.cpp online,从line 1366开始:
bool ValidateCipherModes()
{
...
DESEncryption desE(key);
DESDecryption desD(key);
...
CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
...
CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
...
}
外卡是DESEncryption
和DESDecryption
。让我们看看它:
$ grep -IR DESEncryption *
des.h:typedef DES::Encryption DESEncryption;
所以AES应该干净利落地切入。现在,测试程序:
#include "filters.h"
#include "osrng.h"
#include "modes.h"
#include "files.h"
#include "aes.h"
using namespace CryptoPP;
#include <iostream>
#include <string>
using namespace std;
// g++ -DNDEBUG -g2 -O2 -I. test.cxx ./libcryptopp.a -o test.exe
int main(int argc, char* argv[])
{
AutoSeededRandomPool prng;
string plain = "Now is the time for all good men to come to the aide of their country";
string cipher, recover;
SecByteBlock key(AES::DEFAULT_KEYLENGTH), iv(AES::BLOCKSIZE);
prng.GenerateBlock(key, key.size());
prng.GenerateBlock(iv, iv.size());
AES::Encryption aes1(key, key.size());
CBC_Mode_ExternalCipher::Encryption cbc1(aes1, iv);
StringSource ss1(plain, true, new StreamTransformationFilter(cbc1, new StringSink(cipher)));
AES::Decryption aes2(key, key.size());
CBC_Mode_ExternalCipher::Decryption cbc2(aes2, iv);
StringSource ss2(cipher, true, new StreamTransformationFilter(cbc2, new StringSink(recover)));
cout << "Plain: " << plain << endl;
cout << "Recover: " << recover << endl;
return 0;
}
编译并运行:
$ g++ -DNDEBUG -g2 -O2 -I. test.cxx ./libcryptopp.a -o test.exe
$
$ ./test.exe
Plain: Now is the time for all good men to come to the aide of their country
Recover: Now is the time for all good men to come to the aide of their country
所以一切似乎都按预期工作。
现在,对于这个问题:
AES128CBC: /usr/local/include/cryptopp/misc.h:304: void CryptoPP::memcpy_s(void*, size_t, const void*, size_t):
Assertion `dest != __null' failed.
在AES128 in CBC mode implementation using cryptopp library中,您被告知使用最新的Crypto ++库,因为我们清理了其中的一些。见this comment:
您应该使用最新版本的Crypto ++源代码。我相信这个问题不久前被清除了:
void CryptoPP::memcpy_s(void*, size_t, const void*, size_t): Assertion 'dest != __null' failed
。您可以使用git clone https://github.com/weidai11/cryptopp.git
获取最新来源。
你也接受了Zaph's answer,所以这应该是关于解密和断言麻烦的事情的结束。这标志着我和Stack Overflow社区你不需要额外的帮助或答案。
您可能遇到的问题是将位于/usr/local
的Crypto ++版本与您通过发行版安装的版本sudo apt-get install libcrypto++-dev libcrypto++-doc libcrypto++-utils
混合。断言是混合和匹配它们的经典标志,因为发行版提供了旧版本的库。
如果您注意到我使用的命令行,您将看到:
-DNDEBUG -g2 -O2
以确保我使用与构建库相同的选项-I
以确保我在PWD中使用Crypto ++标头./libcryptopp.a
以确保我链接到PWD中的库的静态版本,并避免运行时链接/加载错误的库您可能正在使用错误的Crypto ++库进行运行时链接。我通过精确控制链接的内容来避免它们,而不依赖于运行时链接/加载器。
您可以自由地使用运行时链接/加载器来执行这些操作,但必须注意确保在运行时获得正确的库。为此,请参阅GNUmakefile | Compiling and Linking。我认为你在第二个案例中被称为 BAD :
错误 :以下内容会产生问题,因为您编译并链接到您的库副本,但在运行时它会链接到发行版的库副本:< / p>
$ ls cryptopp test.cxx $ g++ -DNDEBUG -g2 -O2 -I . test.cxx -o test.exe -L ./cryptopp -lcryptopp
如果未解决,则需要发布Minimal, Complete, and Verifiable example (MCVE)。很可能是断言在您的数据集下触发。我们最近在Trying to do CMAC on VS2013 and found this error. "Assertion failed: (input && length) || !(input || length)"有一个。我们在报告的几小时内检查了修复程序,但不到30天前。
我还需要查看您的编译和链接命令以及ldd
的输出,以查看您要链接的内容。
有时,当您不提供纯文本或密文数据(input0.txt
和output0.txt
)时,我们无能为力,或者您没有提供编译和链接命令等详细信息