d openssl aes массив зашифрованных байтов не является постоянным между выполнениями

Я связываю D с OpenSsl, используя заголовки Deimos openssl для D, и использую компилятор ldc 1.8.0, чтобы попытаться зашифровать строку как небольшой тест. Зашифрованный байтовый массив не соответствует тому, что я ожидал. Когда я запускаю программу и зашифрую строку, а затем расшифрую ее, я получаю свою исходную строку обратно. Но промежуточный зашифрованный байтовый массив не согласован между выполнениями кода.

Поэтому мой вопрос заключается в том, является ли это предполагаемым поведением, и добавляет ли AES в OpenSsl какую-то соль к контенту, чтобы его было сложнее атаковать, или это ошибка с моей стороны?

import std.stdio;
import std.conv;
import std.string;
import std.outbuffer;

import deimos.openssl.aes;

void main()
{
    writeln("hello world");
    const auto encryption_passphrase = "foo!";

    writeln("The encryption key is \"" ~ encryption_passphrase ~ "\"");

    const auto encryption_content = "bar";
    writeln("The to be encrypted content is: \"" ~ encryption_content ~ "\"");

    writeln("The content lenght is " ~  encryption_content.length.to!string);

    writeln("----------");
    writeln("encrypting");

    AES_KEY encryption_key;

    AES_set_encrypt_key(cast(ubyte*) encryption_passphrase.toStringz, 128, &encryption_key);


    OutBuffer buf = new OutBuffer();
    buf.write(encryption_content);

    ubyte[] inbuffer = buf.toBytes();
    ubyte[] encryptedbuffer = new ubyte[inbuffer.length];
    AES_encrypt(&inbuffer[0], &encryptedbuffer[0], &encryption_key);
    writeln("The encrypted content is: \"" ~ (cast(char*)encryptedbuffer).fromStringz ~ "\"");

    writeln("----------");
    writeln("decrypting");
    AES_KEY decryption_key;
    AES_set_decrypt_key(cast(ubyte*)  encryption_passphrase.toStringz, 128, &decryption_key);

    ubyte[] outbuffer = new ubyte[inbuffer.length];

    AES_decrypt(&encryptedbuffer[0], &outbuffer[0], &decryption_key);
    writeln("the decrypted content is: \"" ~ (cast(char*)outbuffer).fromStringz ~ "\"");
}

1 ответ

Решение

Код содержит несколько ошибок с вашей стороны.

Во-первых, вы, кажется, путаете ключевую фразу с ключом. Учитывая, что вы вызываете AES_set_encrypt_key() с размером ключа 128 бит (второй параметр) фактические байты, используемые для ключа, будут 128 битами = 16 байтов, на которые указывает ваш первый параметр. Так как ваш первый параметр указывает на строку с нулем в конце "foo!"все, что находится за пятым байтом, будет непредсказуемым, и фактический используемый ключ, возможно, будет отличаться при каждом запуске этого кода.

Затем вы хотите использовать AES_encrypt() функция для "шифрования ваших данных", и ваши данные являются строкой с нулем в конце "bar", Но эта функция фактически выполняет операции с блоками фиксированного размера 128 бит = 16 байтов, независимо от используемого размера ключа. Страница Википедии об AES объясняет это подробно. Поэтому ожидается, что оба буфера ввода и вывода этой функции будут иметь размер 16 байт. Вы даете параметры функции, которые указывают на буферы неправильного размера.

Те же проблемы существуют и для вашей "дешифрованной" части кода.

Взгляните на этот краткий пример C, который правильно использует эти функции. Это может помочь вам получить правильный код (и сбросить ваши ожидания относительно того, для чего эти функции реализованы). Чтобы достичь того, чего вы действительно хотите, правильно, см. Вики-страницу OpenSSL https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption. У меня нет опыта D программирование, но на первый взгляд привязка Deimos openssl, кажется, обеспечивает всю необходимую функциональность.

Другие вопросы по тегам