d openssl aes 加密字节数组在执行之间不是常量

d openssl aes encrypted byte array is not constant between executions

我正在使用 D 的 Deimos openssl headers 将 D 链接到 OpenSsl,并且我正在使用 ldc 1.8.0 编译器,以尝试加密字符串作为一个小测试。 加密的字节数组与我的预期不一致。 当我 运行 程序并加密字符串并在之后解密时,我得到了我的原始字符串。 但是中间加密字节数组在代码执行之间不一致。

所以我的问题是,这是预期的行为吗?OpenSsl 中的 AES 是否在内容中添加了某种盐以使其更难受到攻击,或者这是我的错误?

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 ~ "\"");
}

您的代码有几处错误。

首先,您似乎混淆了密码和密钥。鉴于您调用 AES_set_encrypt_key() 的密钥大小为 128 位(第二个参数),用于密钥的实际字节将是第一个参数指向的 128 位 = 16 字节。由于您的第一个参数指向一个以 0 结尾的字符串 "foo!",因此第五个字节之后的所有内容都将无法预测,并且每次您 运行 此代码时使用的实际密钥可能会有所不同。

那你要用AES_encrypt()函数来"encrypt your data"而你的数据就是0结尾的字符串"bar"。但该函数实际上对固定大小为 128 位 = 16 字节的块执行操作,与使用的密钥大小无关。 wikipedia page about AES 有详细解释。因此,该函数的输入和输出缓冲区都应为 16 字节的缓冲区。您提供的函数参数指向错误大小的缓冲区。

您的 "decryption" 部分代码也存在同样的问题。

看看this concise C example that uses these functions correctly. That might help you getting your code right (and resetting your expectations of what these functions are implemented to do). To achieve what you actually want in the correct way, see the OpenSSL wiki page EVP Symmetric Encryption and Decryption。我没有 D 编程经验,但乍一看,Deimos openssl 绑定似乎提供了所需的所有功能。