模板化模式对象和外部密码对象有什么区别?
的解释*_ExternalCiphers
给出在modes.h,它出现在网络上CipherModeDocumentation Class Reference。它并不容易找到,我只是因为与消息来源密切合作才知道它。
正文如下:
从这个 [CipherModeDocumentation] 派生的每个类都定义了两种类型:Encryption 和 Decryption,这两种类型都实现 SymmetricCipher 接口。对于每种模式都有两个类,其中一个是模板类,另一个的名称以“_ExternalCipher”结尾。
“外部密码”模式对象保存对底层分组密码的引用,而不是保存它的实例。该引用必须传递给构造函数。对于“密码持有者”类,CIPHER 模板参数应该是从 BlockCipherDocumentation 派生的类,例如 DES 或 AES。
因此,区别在于操作模式与密码的关联方式——字面上是外部与内部。
External- 下面是两个不同的对象。第一个是对称密码,第二个是操作方式:
AES::Encryption aes(key, ...);
CBC_Mode_ExternalCipher::Encryption cbc(aes, ...);
Internal- 下面是一个单一的对象。操作模式“有一个”通过模板实例化的对称密码:
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,从周围开始1366行:
bool ValidateCipherModes()
{
...
DESEncryption desE(key);
DESDecryption desD(key);
...
CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
...
CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
...
}
所以通配符是DESEncryption
and 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.
In 使用 cryptopp 库以 CBC 模式实现 AES128,您被告知使用最新的 Crypto++ 库,因为我们清理了其中的一些库。看这条评论:
您应该使用最新版本的 Crypto++ 源代码。我相信这个问题不久前就已经解决了:void CryptoPP::memcpy_s(void*, size_t, const void*, size_t): Assertion 'dest != __null' failed
。您可以通过以下方式获取最新资源git clone https://github.com/weidai11/cryptopp.git
.
你也接受了扎夫的回答,所以这应该是关于解密和断言的麻烦的事情的结束。这向我和 Stack Overflow 社区表明您不需要额外的帮助或答案。
你的问题是likely遇到的是混合您位于的 Crypto++ 版本/usr/local
与您通过发行版安装的那个sudo apt-get install libcrypto++-dev libcrypto++-doc libcrypto++-utils
。断言是混合和匹配它们的经典标志,因为发行版提供了旧版本的库。
如果您记下我使用的命令行,您将看到:
-
-DNDEBUG -g2 -O2
确保我使用与构建库相同的选项
-
-I
确保我在 PWD 中使用 Crypto++ 标头
-
./libcryptopp.a
确保我链接到 PWD 中库的静态版本,并避免运行时链接/加载错误的库
您可能在运行时链接了错误的 Crypto++ 库。我通过精确控制链接的内容来避免它们,而不是依赖于运行时链接/加载器。
您可以自由地使用运行时链接/加载器来执行这些操作,但必须注意确保您在运行时获得正确的库。为此,请参阅GNUmake 文件 |编译和链接。我认为你属于第二种情况BAD:
Bad:以下内容会产生问题,因为您针对库的副本进行编译和链接,但在运行时它链接到发行版的库副本:
$ ls
cryptopp test.cxx
$ g++ -DNDEBUG -g2 -O2 -I . test.cxx -o test.exe -L ./cryptopp -lcryptopp
如果还没有解决,那么您需要发布一个最小、完整且可验证的示例 (MCVE)。很可能在您的数据集下触发断言。我们最近有一个在。我们在报告发布后几小时内就签入了修复程序,距今还不到 30 天。
我还需要查看您的编译和链接命令以及输出ldd
看看你链接的是什么。
有时,当您不提供明文或密文数据时,我们无能为力(input0.txt
and output0.txt
),或者您不提供编译和链接命令等详细信息。