AES解密密码++意外停止

问题描述 投票:2回答:1

我正在尝试使用Crypto ++ libary进行aes加密和解密“字节数组”(vector<unsigned char>)。加密工作正常且正确。

我的函数生成一个随机IV,并将其置于加密数据的前面。当然解密会读取IV。我修改了this答案中的代码,因此它可以与我的向量和CTR /无填充一起使用。

它在stfDecryptor.Put(...)行中崩溃了。首先,我认为数据或IV读取不正确,但是经过检查后,情况并非如此。

我希望我在这里犯了一个非常明显的错误。

谢谢大家:)

课堂电话:

//The code is not clean, i want to get it working first and then clean it up. 
auto key = Helper::RandomBytes(16); //returns "byte Array" with random Bytes
auto data = Helper::UTF8String2ByteArray("HELLO WORLD!");
auto encrypted = AESCrypt::encrypt(key, data);
cout << Helper::ByteArray2HexString(key);
cout << "\r\n";
cout << Helper::ByteArray2HexString(data);
cout << "\r\n";
cout << Helper::ByteArray2HexString(encrypted);
cout << "\r\n";    
auto decrypted = AESCrypt::decrypt(key, encrypted);
auto clear = Helper::ByteArray2UTF8String(decrypted);

Class:

vector<unsigned char> AESCrypt::encrypt(vector<unsigned char> key_, vector<unsigned char> data)
{
    vector<unsigned char> iv_ = Helper::RandomBytes(16); //returns "byte Array" with random Bytes

    byte key[AES::DEFAULT_KEYLENGTH], iv[AES::BLOCKSIZE];

    for (size_t i = 0; i < AES::DEFAULT_KEYLENGTH; i++)
        key[i] = key_[i];
    for (size_t i = 0; i < iv_.size(); i++)
        iv[i] = iv_[i];

    AES::Encryption aesEncryption(key, AES::DEFAULT_KEYLENGTH);
    CTR_Mode_ExternalCipher::Encryption ctrEncryption(aesEncryption, iv);

    vector<unsigned char> encrypted;
    StreamTransformationFilter stfEncryptor(
        ctrEncryption,
        new VectorSink(encrypted),
        BlockPaddingSchemeDef::NO_PADDING);

    stfEncryptor.Put((const byte*)data.data(), data.size());
    stfEncryptor.MessageEnd();

    vector<unsigned char> output(encrypted.size() + 16);

    for (size_t i = 0; i < 16; i++)
        output[i] = iv[i];
    for (size_t i = 0; i < encrypted.size(); i++)
        output[16 + i] = encrypted[i];

    return output;
}

vector<unsigned char> AESCrypt::decrypt(vector<unsigned char> key_, vector<unsigned char> data_)
{    
    byte key[AES::DEFAULT_KEYLENGTH], iv[AES::BLOCKSIZE];
    for (size_t i = 0; i < AES::DEFAULT_KEYLENGTH; i++)
        key[i] = key_[i];
    for (size_t i = 0; i < 16; i++)
        iv[i] = data_[i];

    vector<unsigned char> data(data_.size() - 16);
    for (size_t i = 0; i < data.size(); i++)
    {
        data[i] = data_[16 + i];
    }

    AES::Decryption aesDecryption(key, AES::DEFAULT_KEYLENGTH);
    CTR_Mode_ExternalCipher::Decryption ctrDecryption(aesDecryption, iv);

    vector<unsigned char> decrypted;
    StreamTransformationFilter stfDecryptor(
        ctrDecryption,
        new VectorSink(decrypted),
        BlockPaddingSchemeDef::NO_PADDING);

    stfDecryptor.Put((const byte*)data.data(), data.size()); //this is where it crashes
    stfDecryptor.MessageEnd();

    return decrypted;

}

这里是CallStack的图片:

enter image description here

这是在C ++++库中停止的行:

CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());
c++ encryption aes crypto++
1个回答
1
投票
这是在CryptoPP库内部停止的行:
CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());

计数器模式(CTR)使用正向变换进行加密和解密。通过对IV /计数器进行加密来生成密钥流,然后将密钥流与明文或密文进行异或。

您应该更改此:

AES::Decryption aesDecryption(key, AES::DEFAULT_KEYLENGTH); CTR_Mode_ExternalCipher::Decryption ctrDecryption(aesDecryption, iv);

为此:

AES::Encryption aesDecryption(key, AES::DEFAULT_KEYLENGTH);
CTR_Mode_ExternalCipher::Decryption ctrDecryption(aesDecryption, iv);

通知计数器模式解密使用加密器。

Wiki中有一个计数器模式的示例,我们将此问答作为外部密码示例的一部分。另请参阅Crypto ++ Wiki上的CTR Mode

这里是复制者。


$ cat test.cxx #include "cryptlib.h" #include "secblock.h" #include "filters.h" #include "modes.h" #include "aes.h" #include <iostream> #include <string> int main (int argc, char* argv[]) { using namespace CryptoPP; SecByteBlock key(16), iv(16); std::memset(key, 0xff, key.size()); std::memset( iv, 0x88, iv.size()); std::string message, encrypted, decrypted; message = "Now is the time for all good men " "to come to the aide of their country."; AES::Encryption aesEncryption(key, key.size()); CTR_Mode_ExternalCipher::Encryption ctrEncryption(aesEncryption, iv); StreamTransformationFilter stfEncryptor( ctrEncryption, new StringSink(encrypted)); stfEncryptor.Put((const byte*)&message[0], message.size()); stfEncryptor.MessageEnd(); AES::Encryption aesDecryption(key, key.size()); CTR_Mode_ExternalCipher::Decryption ctrDecryption(aesDecryption, iv); StreamTransformationFilter stfDecryptor( ctrDecryption, new StringSink(decrypted)); stfDecryptor.Put((const byte*)&encrypted[0], encrypted.size()); stfDecryptor.MessageEnd(); std::cout << "Message: " << message << std::endl; std::cout << "Recovered: " << decrypted << std::endl; return 0; }

和:

$ g++ -g2 -O1 test.cxx ./libcryptopp.a -o test.exe
$ ./test.exe
Message: Now is the time for all good men to come to the aide of their country.
Recovered: Now is the time for all good men to come to the aide of their country.
© www.soinside.com 2019 - 2024. All rights reserved.