模板对象和外部密码对象有什么区别? [英] What's the difference between templated mode object and external cipher object?

查看:238
本文介绍了模板对象和外部密码对象有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与标题一样,我在此声明之前在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(restoredtext)
);

stfDecryptor.Put(reinterpret_cast< const unsigned char *>(ciphertext.c_str()),ciphertext.size());
stfDecryptor.MessageEnd();

所有都很好 strong>运行时:

  AES128CBC:/usr/local/include/cryptopp/misc.h:304: void CryptoPP :: memcpy_s(void *,size_t,const void *,size_t):断言`dest!= __null'失败。 
中止(核心转储)

应该不一样?



我看过这<

blockquote>

模板模式对象和外部密码对象之间有什么区别?


> * _ ExternalCiphers modes.h ,它会显示在网络上 CipherModeDocumentation类参考 。它不容易找到,我只知道它,因为我与来源密切合作。



这里是文本:


从这一个派生的每个类[CipherModeDocumentation]定义了两种类型,Encryption和Decryption,它们都实现了SymmetricCipher接口。对于每个模式,有两个类,其中一个是模板类,另一个具有以_ExternalCipher结尾的名称。



外部密码模式对象持有对底层块密码的引用,而不是持有它的实例。引用必须传递给构造函数。对于密码保持器类,CIPHER模板参数应该是从BlockCipherDocumentation派生的类,例如DES或AES。


外部 - 下面是是两个不同的对象。第一个是对称密码,第二个是操作模式:

  AES ::加密aes ); 
CBC_Mode_ExternalCipher :: Encryption cbc(aes,...);

内部 。操作模式具有通过模板实例化的对称密码:

  CBC_Mode< AES> ::加密enc ,...); 







而使用模板模式我在运行时...有这个错误...


OK,这是一个不同的问题。让我们看看如何使用它:

  $ grep -IRCBC_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 ::加密模式E(desE,iv);
...
CBC_Mode_ExternalCipher :: Decryption modeD(desD,iv);
...
}

所以通配符是 DESEncryption DESDecryption 。让我们看看它:

  $ grep -IR DESEncryption * 
des.h: typedef DES :: Encryption DESEncryption;

所以AES应该干净地插入。现在,测试程序:

  #includefilters.h
#includeosrng.h
#includemodes.h
#includefiles.h
#includeaes.h
使用命名空间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 =现在是所有好男人来到他们国家助手的时候了;
string cipher,recover;

SecByteBlock键(AES :: DEFAULT_KEYLENGTH),iv(AES :: BLOCKSIZE);
prng.GenerateBlock(key,key.size());
prng.GenerateBlock(iv,iv.size());

AES ::加密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:<恢复< endl;

return 0;
}

编译并运行:

  $ g ++ -DNDEBUG -g2 -O2 -I。 test.cxx ./libcryptopp.a -o test.exe 
$

$ ./test.exe
普通:现在是所有好男人来到他们的国家
恢复:现在是所有好男人来到他们国家的助手的时间

现在,对于这个问题:

  AES128CBC:/usr/local/include/cryptopp/misc.h:304:void CryptoPP :: memcpy_s void *,size_t,const void *,size_t):
断言`dest!= __null'失败。

AES128在CBC模式实现使用cryptopp库,你被告知要使用最新的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 获取最新来源。


您还接受了 Zaph的回答,这样应该是事情的结束给你麻烦与解密和断言。这告诉我和Stack Overflow社区你不需要额外的帮助或答案。



你可能遇到的问题是混合你的版本的Crypto ++位于 / usr / local 与您安装通过您的发行版与 sudo apt-get install libcrypto ++ - dev libcrypto ++ - doc libcrypto ++ - utils 。 assert是混合和匹配它们的经典标志,因为distro提供了一个旧版本的库。



如果你注意到我使用的命令行,请参阅:




  • -DNDEBUG -g2 -O2 与用于构建库的相同选项

  • -I ,以确保我在PWD中使用Crypto ++标题

  • ./ libcryptopp.a 以确保我链接到PWD中的库的静态版本,并避免运行时链接/加载错误的库



你可能是运行时链接到错误的Crypto ++库。我通过控制确切的链接,而不依赖于运行时链接/加载程序来避免它们。






使用运行时链接/加载器来做这些事情,但是必须注意确保在运行时获得正确的库。有关详情,请参阅 GNUmakefile |编译和链接。我认为你在第二种情况下被称为 BAD


strong> :

:以下操作会创建问题,因为您编译并链接到库的副本,但在运行时它链接到发行版的库:

  $ ls 
cryptopp test.cxx

$ g ++ -DNDEBUG -g2 -O2 -I。 test.cxx -o test.exe -L ./cryptopp -lcryptopp




< hr>

如果尚未解决,则需要发布最小,完整和可验证示例MCVE)。很可能是assert在您的数据集下触发。我们最近在尝试在VS2013上执行CMAC,发现此错误。 断言失败:(输入&&长度)||!(输入||长度)。我们在小于30天前的报告小时内检查了修复。



我还需要看到你的编译和链接命令, ldd 查看您要关联的内容。



有时候,明文或密文数据( input0.txt output0.txt ),或者您不提供详细信息像编译和链接命令。


As in the title, I am looking for the difference in the cryptopp library between this declaration:

CBC_Mode<AES>::Decryption 
cbcDecryption.SetKeyWithIV(key, AES::DEFAULT_KEYLENGTH, iv);

and this one:

AES::Decryption aesDecryption(key, AES::DEFAULT_KEYLENGTH);
CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );

Moreover, I can't understand why with this:

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();

all works fine while using the templated mode I have this error during run time:

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)

Shouldn't be the same?

I have looked at this but I didn't understand well the difference and searching over the net I couldn't find an answer to my problem.

解决方案

What's the difference between templated mode object and external cipher object?

The explanation for the *_ExternalCiphers is given in modes.h, and it shows up on the web in CipherModeDocumentation Class Reference. Its not easy to find, and I only know about it because I work closely with the sources.

Here's the text:

Each class derived from this one [CipherModeDocumentation] defines two types, Encryption and Decryption, both of which implement the SymmetricCipher interface. For each mode there are two classes, one of which is a template class, and the other one has a name that ends in "_ExternalCipher".

The "external cipher" mode objects hold a reference to the underlying block cipher, instead of holding an instance of it. The reference must be passed in to the constructor. For the "cipher holder" classes, the CIPHER template parameter should be a class derived from BlockCipherDocumentation, for example DES or AES.

So the difference is how the mode of operation associates with the cipher - literally external versus internal.

External - below are two distinct objects. The first is the symmetric cipher, the second is the mode of operation:

AES::Encryption aes(key, ...);
CBC_Mode_ExternalCipher::Encryption cbc(aes, ...);

Internal - below is a single object. The mode of operation "has a" symmetric cipher that's instantiated through the template:

CBC_Mode<AES>::Encryption enc(key, ...);


all works fine while using the templated mode I have this error during run time...

OK, this is a different problem. Let's see how to use it:

$ 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);

You can find validat1.cpp online, starting around line 1366:

bool ValidateCipherModes()
{
    ...
    DESEncryption desE(key);
    DESDecryption desD(key);

    ...
    CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
    ...
    CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
    ...
}

So the wild card is DESEncryption and DESDecryption. Let's see about it:

$ grep -IR DESEncryption *
des.h:typedef DES::Encryption DESEncryption;

So AES should cut-in cleanly. Now, the test program:

#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;
}

Compile and run:

$ 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

So everything appears to be working as expected.


Now, for this issue:

AES128CBC: /usr/local/include/cryptopp/misc.h:304: void CryptoPP::memcpy_s(void*, size_t, const void*, size_t):
Assertion `dest != __null' failed.

In AES128 in CBC mode implementation using cryptopp library, you were told to use the latest Crypto++ library because we cleaned up a few of them. See this comment:

You should use the latest version of the Crypto++ sources. I believe this issue was cleared some time ago: void CryptoPP::memcpy_s(void*, size_t, const void*, size_t): Assertion 'dest != __null' failed. You can get the latest sources with a git clone https://github.com/weidai11/cryptopp.git.

You also accepted Zaph's answer, so that should be the end of things with respect to you troubles with decryption and the assert. That signaled to me and the Stack Overflow community you did not need additional help or answers.

The problem you are likely running into is mixing your version of Crypto++ located at /usr/local with the one you installed via your distro with sudo apt-get install libcrypto++-dev libcrypto++-doc libcrypto++-utils. The assert is a classic sign of mixing and matching them because the distro provides an old version of the library.

If you take note of the command line I used, you will see:

  • -DNDEBUG -g2 -O2 to ensure I'm using the same options as used to build the library
  • -I to ensure I'm using the Crypto++ headers in PWD
  • ./libcryptopp.a to ensure I link to the static version of the library in PWD and avoid runtime linking/loading with the wrong library

You are probably runtime linking with the wrong Crypto++ library. I avoid them by controlling exactly what is linked, and not depending on the runtime link/loader.


You are free to use the runtime link/loader to do these things, but care must be taken to ensure you get the right library at runtime. For that, see GNUmakefile | Compiling and Linking. I think you are in the second case called out as BAD:

Bad: the following will create problems because you compile and link against your copy of the library, but at runtime it links to the distro's copy of the library:

$ ls
cryptopp        test.cxx

$ g++ -DNDEBUG -g2 -O2 -I . test.cxx -o test.exe -L ./cryptopp -lcryptopp


If its not solved, then you need to post a Minimal, Complete, and Verifiable example (MCVE). It could well be that an assert fires under your data set. We had one recently at Trying to do CMAC on VS2013 and found this error. "Assertion failed: (input && length) || !(input || length)". We checked-in the fix within hours of the report, which is less than 30 days ago.

I also need to see your compile and link command, and the output of ldd to see what you are linking against.

Sometimes, there's nothing we can do when you don't provide the plain text or cipher text data (input0.txt and output0.txt), or you don't provide details like the compile and link command.

这篇关于模板对象和外部密码对象有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆