【问题标题】:Encrypt unsigned int value in form of bits stream by AES_CFB mode通过 AES_CFB 模式以比特流的形式加密 unsigned int 值
【发布时间】:2015-03-02 10:11:32
【问题描述】:

我有 c++ 代码,它使用 AES_CFB 将字符串加密为纯文本并生成相同大小的密文,但问题是输入和输出的数据类型,所以谁能帮我让它加密一个无符号整数并生成unsigned int number ciphertext withe 保持明文和 Chipertext 相同的长度(位长度)。

string ENCRYPTOR(const std::string& PlainText)
{
    byte key[16]= "1234ff";//  byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ];
    byte iv[16]= "123456";//byte iv[ CryptoPP::AES::BLOCKSIZE ];

    std::string CipherText;

    // Encryptor
    CryptoPP::CFB_Mode< CryptoPP::AES >::Encryption encryptor( key, sizeof(key), iv);

    // Encryption
    CryptoPP::StringSource( PlainText, true,
        new CryptoPP::StreamTransformationFilter( encryptor,
            new CryptoPP::StringSink( CipherText ) ) ); 

    return (CipherText);
}

string DECRYPTOR(const string& CipherText)
{
    byte key[16]= "1234ff";
    byte iv[16]= "123456"; 

    std::string RecoveredText;

    // Decryptor
    CryptoPP::CFB_Mode< CryptoPP::AES >::Decryption decryptor( key, sizeof(key), iv );

    // Decryption
    CryptoPP::StringSource( CipherText, true,
        new CryptoPP::StreamTransformationFilter( decryptor,
            new CryptoPP::StringSink( RecoveredText ) ) ); 

    return (RecoveredText);
}

int main()
{
    string ciphertext;
    string plaintext = "3555";
    ciphertext= ENCRYPTOR(plaintext);
    string retrivdat = DECRYPTOR(ciphertext);

    cout<<"The plaintext data is:  "<<plaintext<<endl;
    cout<<"The ciphertextdata is:  "<<ciphertext<<endl;
    Coot<<"The retrieved data is:  "<<retrivdat<<end;

    return 0;
}

输出是

The plaintext data is:  3555
The chepertext data is:  ï¥R_
The retrieved data is:  3555

【问题讨论】:

  • CryptoPP::StringSource 有一个构造函数将const byte* 指针指向一个缓冲区,以及该缓冲区的长度。如果你有int x要加密,只需相应地传递(const byte*)&amp;xsizeof(x)
  • @IgorTandetnik 备注 1)您只能使用大多数 API 加密字节 2)根据问题,使用 unsigned int 和 3)请确保使用相同大小的 int 和每台机器上的相同字节序 4) 可能不是最小的编码(但我们不知道最小/最大尺寸)
  • 似乎您已经成功地做到了这一点(尽管首先转换为字符串对我来说似乎不是最佳选择),您的问题是什么?您需要最小位大小吗?以字节为单位的最小大小,某种最大值?
  • 谢谢@Maarten 和伊戈尔。实际上,我需要将整数 PLAINTEXT 值加密为具有相同 SIZE 的整数 CHIPERTEXT 值。例如,明文值是 453(3 个字节),CHIPERTEXT 必须由具有相同大小(3 个字节)的任何整数值组成。换句话说,CHIPERTEXT SIZE 必须是 INTEGER 并且具有与 PLAINTEXT 值相同的 SIZE。

标签: c++ encryption encoding crypto++


【解决方案1】:

所以你可以:

  1. 将数字编码为最小 x 字节数,例如使用无符号大端数
  2. 使用 CFB 加密,得到相同数量的 x 字节
  3. 解密号码
  4. 从生成的 x 字节中解码数字(当然使用相同的编码方案)

如果您想将密文视为数字,则必须将密文解码为(有符号或无符号)数字。

请注意,您仍然需要处理 IV 的唯一性。如果您需要存储 IV,那么开销会很大。

【讨论】:

  • 如果你被 IV 困扰,看看格式保留加密。
  • 谢谢@Maarten,我试过了,但是编码和解码过程会生成一个比明文更长的芯片文本。我还担心计算开销。
  • 用这个无符号整数编码 n = ...; ostringstream oss; oss > n;
  • 好的,所以根据规范,&lt;&lt; 运算符生成字符串而不是编码为字节。使用例如this answer 代替。
【解决方案2】:

通过 AES_CFB 模式以比特流的形式加密 unsigned int 值

Igor 和 Owlstead 提出了一些关于整数大小和字节序的有效观点。避免它们的最简单解决方案可能是将整数编码为字符串:

unsigned int n = ...;
ostringstream oss;

oss << n;

string plainText = oss.str();

稍后,您可以将其转换回来:

string recovered = ...;
istringstream iss(recovered);

unsigned int n;
iss >> n;

byte key[16]= "1234ff";//  byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ];
byte iv[16]= "123456";//byte iv[ CryptoPP::AES::BLOCKSIZE ];

您的密钥和 IV 太小。因此,您应该收到编译器警告。 AES::DEFAULT_KEYLENGTH 是 16,因此密钥至少需要 16 个字符。 AES::BLOCKSIZE 是 16,所以初始化向量至少需要 16 个字符。

如果上面的代码恰好可以工作,那纯粹是因为运气。您可能应该访问 Crypto++ wiki 上的 CFB Mode。它有一个工作示例。

或者,使用PBKDF 拉伸短键和短IV。您可以在 Stack Overflow 上的 Crypto++ pbkdf2 output is different than Rfc2898DeriveBytes (C#) and crypto.pbkdf2 (JavaScript) 找到一个示例。


chepertext数据为:ï¥R_

您可以通过以下方式使其可打印:

string encoded;
HexEncoder hexer(new StringSink(encoded));

hexer.Put((byte*)cipherText.data(), cipherText.size());
hexer.MessageEnd();

cout << encoded << endl;

或者,您可以使用以下(使用管道):

string encoded;

StringSource ss(cipherText, true,
    new HexEncoder(
        new StringSink(encoded)));

cout << encoded << endl;

HexEncoderHexDecoder 在 Crypto++ wiki 上也有讨论。

【讨论】:

  • 感谢@jww,密文[ï¥R_]长度=3字节,所以我无法获得相同大小的整数密文。
  • "ï¥R_" 对我来说看起来像 4 个字节。 "ï""¥""R""_"。你从哪里得到 3 个字节?
  • 哦,对不起,你是对的,它是 4 个字节。如您所见,整数值 3555 =110111100011(2 个字节)但其芯片文本ï¥R_(4 个字节)。因为它被视为单个字符。如果我将其更改为整数纯文本,我得到了错误的结果
猜你喜欢
  • 2016-12-13
  • 2019-09-29
  • 2012-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-05
  • 2022-10-01
  • 2013-06-15
相关资源
最近更新 更多