如何获取/设置CFB_Mode加密对象的内部状态? [英] How to get/set internal state of a CFB_Mode Encryption Object?

查看:506
本文介绍了如何获取/设置CFB_Mode加密对象的内部状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以创建一个新的加密对象,它与先前创建的加密对象具有相同的内部状态(我需要这个,只保留函数调用之间的IV,而不是整个对象)?



我认为应该可以使用函数 GetNextIV 但我没有得到正确的结果。在下面的示例中,字符串这是文本被编码,正确的编码文本是:

  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>

使用命名空间CryptoPP;

void printHex(const byte in){
std :: cout<< std :: setfill('0')<< std :: setw(2)<< std :: hex<< (int)in<< - ;
}

int main(){

//生成一个随机密钥和IV
AutoSeededRandomPool rnd;
SecByteBlock键(0x00,AES :: DEFAULT_KEYLENGTH);
rnd.GenerateBlock(key,key.size());
byte iv [AES :: BLOCKSIZE];
rnd.GenerateBlock(iv,AES :: BLOCKSIZE);

//按字节加密
//这将产生正确的加密文本
byte 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;

//逐字节加密只保留每次迭代的IV
//这不是预期的输出,如何得到它?
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;
}


解决方案


我认为应该可以用函数 GetNextIV 但我没有得到正确的结果...


很遗憾,没有。以下是来自 cryptlib.h GetNextIV 的注释:

  //!为下一个消息获得安全IV 
/ *!在完成加密一条消息并准备开始下一条消息后,应调用此方法。
调用它之后,必须在再次使用此对象之前调用SetKey()或Resynchronize()。
此方法未在解密对象上实现。 * /
virtual void GetNextIV(RandomNumberGenerator& rng,byte * IV);

因此 GetNextIV 满足密码对于不同消息的IV要求,而不是对于当前消息的内部状态。



第二线索它不揭示内部状态是PRNG参数。如果你使用 NullRNG(),那么它应该抛出异常。内部状态不应随机化:)







如何 你正在寻找的是 m_register m_temp



modes.h

/ p>

  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(){returnCFB;}

protected:
unsigned int GetBytesPerIteration()const {return m_feedbackSize;}
byte * GetRegisterBegin(){return m_register + BlockSize() - m_feedbackSize;}
bool CanIterate 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

  void CFB_ModePolicy :: Iterate(byte * output,const byte * input,CipherDir dir,size_t iterationCount)
{
assert(m_cipher-> IsForwardTransformation()); // CFB模式需要底层块密码的加密方向,甚至可以解密
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); //在in-place解密的情况下进行复制
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模式需要底层块密码的加密方向,甚至可以解密
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);
}






p>如何设置 CFB_Mode加密对象的内部状态?


这一个更容易。只需调用 SetKeyWithIV 重新同步


Is it possible to create a new Encryption object that has the same internal state as a previously created Encryption object (I need this, to only keep the IV between function calls, and not the whole object)?

I thought it should be possible with the function GetNextIV but I didn't get the right result. In the following example the string This is the text gets encoded and the correct encoded text is:

94-41-d2-d4-06-05-f6-cd-d0-25-d6-f4-f6-52-55-7b-7c-

But I get:

94-a8-a9-b3-e0-a9-b3-e0-b4-a8-a5-e0-b4-a5-b8-b4-c0-

As you can see only the first byte (94) is encoded right. You can try it with following code sample:

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

解决方案

I thought it should be possible with the function GetNextIV but I didn't get the right result...

Sadly, NO. Here's the comments on GetNextIV from 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);

So GetNextIV is used to get IVs that meet the cipher's IV requirements for distinct messages, and not the internal state for the current message.

The second clue it does not reveal internal state is the PRNG parameter. If you use the NullRNG(), then it should throw an exception. Internal state should not be randomized :)


How to get internal state of a CFB_Mode Encryption Object?

I think the internal state you are looking for is in m_register and m_temp. They are protected and lack accessors, so you will need to modify the library.

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

From modes.cpp:

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


How to set internal state of a CFB_Mode Encryption Object?

This one is easier. Just call SetKeyWithIV or Resynchronize.

这篇关于如何获取/设置CFB_Mode加密对象的内部状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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