kkAyataka / plusaes

Header only C++ AES cipher library
https://kkayataka.github.io/plusaes/doc/index.html
Boost Software License 1.0
183 stars 41 forks source link

larger text cannot decrypt #22

Closed HODAKdev closed 3 years ago

HODAKdev commented 3 years ago

Hi, I've been trying plusaes for a few weeks now and I still can't decrypt the text. look this works well fewfw but when I enlarge the text it no longer didn't decrypt :( where is the problem? maybe it would be better to do example code for encrypt and decrypt and not in the script itself. Thank you for your response :)

kkAyataka commented 3 years ago

Hmm, It is difficult. I don't know your plain data and encryption parameters. I cannot reproduce it.

Is vertexCode read from the file correctly? Encrypted data is binary data, it is not a text string.

encrypted_size

You doesn't use get_padded_encrypted_size function. This function is for encryption.

void decrypt(const std::string & vertexCode) {
    ...
    std::vector<unsigned char> decrypted(vertexCode.size());
}
HODAKdev commented 3 years ago

Hmm, It is difficult. I don't know your plain data and encryption parameters. I cannot reproduce it.

Is vertexCode read from the file correctly? Encrypted data is binary data, it is not a text string.

encrypted_size

You doesn't use get_padded_encrypted_size function. This function is for encryption.

void decrypt(const std::string & vertexCode) {
    ...
    std::vector<unsigned char> decrypted(vertexCode.size());
}

Yes vertexCode from file read correctly. Why should i use get_padded_encrypted_size when decrypting? I just want to decrypt using an encrypted file. This is how I did it...


int main()
{
std::string encrypted_data;
std::ifstream stream;
stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
    stream.open("input.txt");
    std::stringstream vShaderStream;
    vShaderStream << stream.rdbuf();
    stream.close();
    encrypted_data = vShaderStream.str();
}
catch (std::ifstream::failure& e)
{
    std::cout << "ERROR READ FILE" << std::endl;
}

const std::vector<unsigned char> key = plusaes::key_from_string(&"EncryptionKey128");
const unsigned char iv[16] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
};

std::vector<unsigned char> encrypted(112);
encrypted.assign(encrypted_data.begin(), encrypted_data.end());

// decrypt
unsigned long padded_size = 0;
std::vector<unsigned char> decrypted(100);

plusaes::decrypt_cbc(&encrypted[0], encrypted.size(), &key[0], key.size(), &iv, &decrypted[0], decrypted.size(), &padded_size);

std::cout << decrypted.data() << std::endl;

}

kkAyataka commented 3 years ago

stream.open("input.txt");

You should read with binary mode. stream.open("input.txt", std::ios::binary);. But the encrypted data file correctness is more important. If the binary mode was not used when it was written, the file may not be correct.

data size

encrypt_cbc pad the data according to PKCS. The padding size is 1-16 bytes.

The encrypted data size is not the same as the raw data size. We can use get_padded_encrypted_size for padded encrypted data size calculation.

On the other hand, the buffer size of the decryption is the same as the encrypted data size. Usually, you can use the encrypted data size. If you call get_padded_encrypted_size with the encrypted data size, the size is 16-byte larger, because padding size is calculated.

HODAKdev commented 3 years ago

stream.open("input.txt");

You should read with binary mode. stream.open("input.txt", std::ios::binary);. But the encrypted data file correctness is more important. If the binary mode was not used when it was written, the file may not be correct.

data size

encrypt_cbc pad the data according to PKCS. The padding size is 1-16 bytes.

The encrypted data size is not the same as the raw data size. We can use get_padded_encrypted_size for padded encrypted data size calculation.

On the other hand, the buffer size of the decryption is the same as the encrypted data size. Usually, you can use the encrypted data size. If you call get_padded_encrypted_size with the encrypted data size, the size is 16-byte larger, because padding size is calculated.

Oh std::ios::binary i put it there. e Yes i use get_padded_encrypted_size for padded encrypted data size calculation. b It still doesn't decrypt anything and padded_size remains at 0, why? Here is the script I use for encryption.

int main() {

    std::string vertexCode;
    std::ifstream vShaderFile;

    vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    try
    {
        vShaderFile.open("input.txt");
        std::stringstream vShaderStream;
        vShaderStream << vShaderFile.rdbuf();
        vShaderFile.close();
        vertexCode = vShaderStream.str();
    }
    catch (std::ifstream::failure& e)
    {
        std::cout << "ERROR FILE" << std::endl;
    }

    const std::vector<unsigned char> key = plusaes::key_from_string(&"EncryptionKey128");
    const unsigned char iv[16] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    };

    // encrypt
    const unsigned long encrypted_size = plusaes::get_padded_encrypted_size(vertexCode.size());
    std::vector<unsigned char> encrypted(encrypted_size);

    plusaes::encrypt_cbc((unsigned char*)vertexCode.data(), vertexCode.size(), &key[0], key.size(), &iv, &encrypted[0], encrypted.size(), true);

    std::ofstream encryptedCode;
    encryptedCode.open("output.txt");
    encryptedCode << encrypted.data();
    encryptedCode.close();
}
HODAKdev commented 3 years ago

https://user-images.githubusercontent.com/82084934/129265681-6f3b597f-3849-4324-9206-754bff2b1b04.mp4

Here is the code

void encrypt()
{
    const std::string raw_data = "Hello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaesHello, plusaes";
    const std::vector<unsigned char> key = plusaes::key_from_string(&"EncryptionKey128");
    const unsigned char iv[16] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    };
    const unsigned long encrypted_size = plusaes::get_padded_encrypted_size(raw_data.size());
    std::vector<unsigned char> encrypted(encrypted_size);

    plusaes::encrypt_cbc((unsigned char*)raw_data.data(), raw_data.size(), &key[0], key.size(), &iv, &encrypted[0], encrypted.size(), true);

    std::cout << encrypted_size << std::endl;
    std::cout << encrypted.data() << std::endl;

    std::ofstream final_data;
    final_data.open("output.txt");
    final_data << encrypted.data();
    final_data.close();

}
void decrypt()
{
    std::string encrypted_data;
    std::ifstream stream;

    stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    try
    {
        stream.open("output.txt", std::ios::binary);
        std::stringstream vShaderStream;
        vShaderStream << stream.rdbuf();
        stream.close();
        encrypted_data = vShaderStream.str();
    }
    catch (std::ifstream::failure& e)
    {
        std::cout << "ERROR READ FILE" << std::endl;
    }

    const std::vector<unsigned char> key = plusaes::key_from_string(&"EncryptionKey128"); // 16-char = 128-bit
    const unsigned char iv[16] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    };

    std::vector<unsigned char> encrypted(192);
    encrypted.assign(encrypted_data.begin(), encrypted_data.end());

    unsigned long padded_size = 0;
    std::vector<unsigned char> decrypted(192);

    plusaes::decrypt_cbc(&encrypted[0], encrypted.size(), &key[0], key.size(), &iv, &decrypted[0], decrypted.size(), &padded_size);

    std::cout << decrypted.data() << std::endl;
    std::cout << padded_size << std::endl;
}
kkAyataka commented 3 years ago

output.txt is not correct. It is not the same as the std::vector encrypted. final_data << encrypted.data(); is wrong. This code may be buffer over-read.

std::ofstream final_data;
final_data.open("output.txt", std::ios::binary);
final_data.write((char *)encrypted.data(), encrypted.size());
final_data.close();
HODAKdev commented 3 years ago

output.txt is not correct. It is not the same as the std::vector encrypted. final_data << encrypted.data(); is wrong. This code may be buffer over-read.

std::ofstream final_data;
final_data.open("output.txt", std::ios::binary);
final_data.write((char *)encrypted.data(), encrypted.size());
final_data.close();

OMG it works! Thank you very much for your help.