是否可以创建一个与之前创建的Encryption
对象具有相同内部状态的新Encryption
对象(我需要这个,只保留函数调用之间的IV,而不是整个对象)?
我认为应该可以使用函数GetNextIV
,但我没有得到正确的结果。在以下示例中,字符串This is the text
被编码,正确的编码文本为:
94-41-d2-d4-06-05-f6-cd-d0-25-d6-f4-f6-52-55-7b-7c-
但我明白了:
94-a8-a9-b3-e0-a9-b3-e0-b4-a8-a5-e0-b4-a5-b8-b4-c0-
正如您所看到的,只有第一个字节(94
)被编码正确。您可以使用以下代码示例进行尝试:
#include <iostream>
#include <iomanip>
#include <crypto++/modes.h>
#include <crypto++/aes.h>
#include <crypto++/osrng.h>
using namespace CryptoPP;
void printHex(const byte in) {
std::cout << std::setfill('0') << std::setw(2) << std::hex << (int)in << "-";
}
int main() {
// Generate a random key and IV
AutoSeededRandomPool rnd;
SecByteBlock key(0x00, AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock(key, key.size());
byte iv[AES::BLOCKSIZE];
rnd.GenerateBlock(iv, AES::BLOCKSIZE);
// Encrypt byte by byte
// this results in the correct encrypted text
byte text[] = "This is the text";
int msgLen = sizeof(text);
CFB_Mode<AES>::Encryption cfbEncB(key, key.size(), iv);
for (byte* beg = &text[0]; beg != &text[msgLen]; ++beg) {
printHex(cfbEncB.ProcessByte(*beg));
}
std::cout << std::endl;
// Encrypt byte by byte only keeping IV for each iteration
// This is not the expected output, how to get it right?
byte nextiv[AES::BLOCKSIZE];
std::copy(&iv[0], &iv[AES::BLOCKSIZE], &nextiv[0]);
for (byte* beg = &text[0]; beg != &text[msgLen]; ++beg) {
CFB_Mode<AES>::Encryption cfbEncC(key, key.size(), nextiv);
printHex(cfbEncC.ProcessByte(*beg));
cfbEncC.GetNextIV(nextiv);
}
std::cout << std::endl;
}
答案 0 :(得分:1)
我认为应该可以使用函数
GetNextIV
,但我没有得到正确的结果......
可悲的是,不。以下是来自GetNextIV
的{{1}}的评论:
cryptlib.h
因此//! get a secure IV for the next message
/*! This method should be called after you finish encrypting one message and are ready to start the next one.
After calling it, you must call SetKey() or Resynchronize() before using this object again.
This method is not implemented on decryption objects. */
virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV);
用于获取满足密码对不同消息的IV要求的IV,而不是当前消息的内部状态。
它没有显示内部状态的第二个线索是PRNG参数。如果您使用GetNextIV
,那么它应该抛出异常。内部状态不应随机化:)
如何 获取 CFB_Mode加密对象的内部状态?
我认为您正在寻找的内部状态位于NullRNG()
和m_register
。它们受到保护并且缺少访问器,因此您需要修改库。
来自m_temp
:
modes.h
来自class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy>
{
public:
IV_Requirement IVRequirement() const {return RANDOM_IV;}
static const char * CRYPTOPP_API StaticAlgorithmName() {return "CFB";}
protected:
unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;}
bool CanIterate() const {return m_feedbackSize == BlockSize();}
void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount);
void TransformRegister();
void CipherResynchronize(const byte *iv, size_t length);
void SetFeedbackSize(unsigned int feedbackSize);
void ResizeBuffers();
SecByteBlock m_temp;
unsigned int m_feedbackSize;
};
:
modes.cpp
如何 设置 CFB_Mode加密对象的内部状态?
这个更容易。只需致电void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
{
assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
assert(m_feedbackSize == BlockSize());
unsigned int s = BlockSize();
if (dir == ENCRYPTION)
{
m_cipher->ProcessAndXorBlock(m_register, input, output);
m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0);
memcpy(m_register, output+(iterationCount-1)*s, s);
}
else
{
memcpy(m_temp, input+(iterationCount-1)*s, s); // make copy first in case of in-place decryption
m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection);
m_cipher->ProcessAndXorBlock(m_register, input, output);
memcpy(m_register, m_temp, s);
}
}
void CFB_ModePolicy::TransformRegister()
{
assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
m_cipher->ProcessBlock(m_register, m_temp);
unsigned int updateSize = BlockSize()-m_feedbackSize;
memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize);
memcpy_s(m_register+updateSize, m_register.size()-updateSize, m_temp, m_feedbackSize);
}
或SetKeyWithIV
。