c++ - 如何获取/设置 CFB_Mode 加密对象的内部状态?

标签 c++ crypto++

是否可以创建一个新的 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;
}

最佳答案

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

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

//! 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);

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

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


How to get internal state of a CFB_Mode Encryption Object?

认为您正在寻找的内部状态在m_registerm_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:

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?

这个比较简单。只需调用 SetKeyWithIVResynchronize

关于c++ - 如何获取/设置 CFB_Mode 加密对象的内部状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28744134/

相关文章:

c++ - 所有变量是否都根据它们在程序中声明的顺序连续存储?

c++ - 如何将 Cppunit 测试迁移到 GoogleTest?

c++ - 对 STL 容器的安全并行只读访问

使用模板的 C++ 11 异步编程

c++ - 模板化模式对象和外部密码对象有什么区别?

c++ - 使用 Crypto++ 通过 SHA1 生成随机哈希

c++ - QT - 强制对象处理传入信号

c++ - 在解密 session key 期间出现异常 "RSA/OAEP-MGF1(SHA-1): ciphertext length of 154 doesn' t 与此 key 所需的长度 192 匹配

c++ - Eclipse与Crypto++的合作

c++ - 如何在 Crypto++ 中使用 RSA OAEP SHA-256 加密/解密数据