C++ OpenSSL AES仅在某些机器上工作,即使使用静态链接也是如此

C++ OpenSSL AES仅在某些机器上工作,即使使用静态链接也是如此,c++,c,ssl,openssl,aes,C++,C,Ssl,Openssl,Aes,我在Linux上使用OpenSSL 1.1.1进行AES解密。它在我的机器上工作,但在另一台机器上不工作,所以我使用了静态链接。这没用。这里有一个代码: if(EVP_DecryptInit(ctx.get()、EVP_aes_256、cbc_hmac_sha256()、key.impl.data(), nullptr)!=1) { const char*errorString=ERR_error_string(ERR_get_error(),nullptr); 返回; } 在不工作的机器上,

我在Linux上使用OpenSSL 1.1.1进行AES解密。它在我的机器上工作,但在另一台机器上不工作,所以我使用了静态链接。这没用。这里有一个代码:

if(EVP_DecryptInit(ctx.get()、EVP_aes_256、cbc_hmac_sha256()、key.impl.data(),
nullptr)!=1)
{
const char*errorString=ERR_error_string(ERR_get_error(),nullptr);
返回;
}
在不工作的机器上,错误字符串如下所示:

error:0607B083:digital envelope routines:EVP_CipherInit_ex:no cipher set
我的
*上的ldd。因此
文件确认它是静态链接的:

ldd mylib.so
    linux-vdso.so.1 (0x00007ffe971a9000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa3a3b64000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fa3a395c000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa3a373d000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa3a33b4000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa3a3016000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa3a2dfe000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa3a2a0d000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fa3a445b000)
我做错了什么

编辑:

我刚刚发现,
EVP_aes_256_cbc
返回的结果与
EVP_aes_256_cbc_hmac_sha256
和其他几个结果相同。那么,它们之间有什么区别呢

我的目标是替换WinAPI
CryptAcquireContextW(&cryptProv\u0,NULL,MS\u ENH\u RSA\u AES\u PROV\u W,PROV\u RSA\u AES,CRYPT\u VERIFYCONTEXT)


EVP_aes_256_cbc_hmac_sha256()
返回空ptr,
EVP_aes_256_cbc()
返回正确的对象并在两台机器上工作。

不要使用
EVP_aes_256_cbc_hmac_sha256()
。这是一种高度专业化的密码,不适用于一般用途。它仅用于libssl。本页提供了相关文档:

该页最相关的部分是关于密码的:

在CBC模式下使用AES进行身份验证加密,使用SHA256(SHA-2,256位)作为HMAC,密钥长度分别为128和256位。身份验证标记的长度为256位

警告:这不适用于TLS之外的使用,需要调用一些未记录的ctrl函数。这些密码不符合EVP AEAD接口

换句话说,如果您不了解此密码未记录方面的详细信息,请不要触摸它。其中一个未记录的方面是,并非所有平台都支持它。在某些平台上,EVP_aes_256_cbc_hmac_sha256()仅返回空值,例如,请参阅:


这就是为什么它在某些机器上适用,但在其他机器上不适用的最可能原因。

如果这是一个链接问题,您的程序甚至不会运行。如何在第一台计算机上设置密码?你能比较两台计算机的
openssl.cnf
吗?@Mathieu我的意思是共享对象在每台计算机上可能不同。对于静态链接,这个问题不应该存在。这是一个完美的例子,说明了为什么将四个函数调用塞进一行,例如
if(EVP_DecryptInit(ctx.get(),EVP_aes_256_cbc_hmac_sha256(),_key.impl.data(),nullptr)!=1)
是一个非常糟糕的主意。在这四个函数调用中,您根本不知道哪一个坏了。你怎么知道不是ctx.get()或者甚至不是
\u key.impl.data()
在某些系统上发生故障并导致级联故障?你不知道。但是,如果您单独进行每个调用,检查每个调用是否成功并记录失败,您就会知道。对于无法解决的问题,10 LOC?糟糕。您是否收到与“EVP_aes_256_cbc()”完全相同的错误,即“无密码集”错误?从EVP_DecryptInit返回的唯一原因是您的输入密码是否为NULL,即“EVP_aes_256_cbc()”返回NULL(您可以添加一些调试以确认是否为NULL)。如果发生这种情况,那么某个地方出现了严重错误…@AndrewHenle
EVP\u aes\u 256\u cbc\u hmac\u sha256()
返回null ptr,这就是错误消息所说的。