OpenSSL链接未定义的引用'EVP_MD_CTX_new'和'... fre'

问题描述:

我正在尝试使用openssl库提供的哈希算法。 我安装了openssl和libssl-dev。版本是1.1.0f。 我尝试运行openssl.org站点的示例代码:OpenSSL链接未定义的引用'EVP_MD_CTX_new'和'... fre'

#include <stdio.h> 

#include <openssl/evp.h> 

int main(int argc, char *argv[]){ 
EVP_MD_CTX *mdctx; 
const EVP_MD *md; 
char mess1[] = "Test Message\n"; 
char mess2[] = "Hello World\n"; 
unsigned char md_value[EVP_MAX_MD_SIZE]; 
int md_len, i; 

if(!argv[1]) { 
    printf("Usage: mdtest digestname\n"); 
    exit(1); 
} 

md = EVP_get_digestbyname(argv[1]); 

if(!md) { 
    printf("Unknown message digest %s\n", argv[1]); 
    exit(1); 
} 

mdctx = EVP_MD_CTX_new(); 
EVP_DigestInit_ex(mdctx, md, NULL); 
EVP_DigestUpdate(mdctx, mess1, strlen(mess1)); 
EVP_DigestUpdate(mdctx, mess2, strlen(mess2)); 
EVP_DigestFinal_ex(mdctx, md_value, &md_len); 
EVP_MD_CTX_free(mdctx); 

printf("Digest is: "); 
for (i = 0; i < md_len; i++) 
    printf("%02x", md_value[i]); 
printf("\n"); 

exit(0); 
} 

我尝试编译此:

gcc digest_example.c -lcrypto -lssl 

,编译器给出了错误:

digest_example.c:(.text+0xbc): undefined reference to `EVP_MD_CTX_new' 
digest_example.c:(.text+0x138): undefined reference to `EVP_MD_CTX_free' 
collect2: error: ld returned 1 exit status 

说实话,我很无能。我通过编译安装并重新安装了两次OpenSSL。另外,所有其他命令都没有问题。只是这两个。链接时是否需要使用其他库?

感谢您的帮助。

+0

使用'gcc digest_example.c -lssl -lcrypto',*** not ***'gcc digest_example.c -lcrypto -lssl'。 LD是单通链接器。 'libssl'依赖于'libcrypto',所以'libcrypto'需要遵循'libssl'。另一种方法是使用'--start-group --end-group'链接器选项。另请参阅['ld(1)'](https://linux.die.net/man/1/ld)手册页。 – jww

+0

-lssl ans -lcrypto的顺序没有使它工作。我将它们全部切换,没有任何区别。看来,链接器和头文件使用了不同的OpenSSL库。 –

+0

OpenSSL 1.1.0头文件和库位于您的计算机上时的状态。注意:我知道的所有发行版都提供OpenSSL 1.0.2;不是OpenSSL 1.1.0。 – jww

您似乎在使用旧版本的openssl(< 1.1.0)。也许你已经下载并安装了更新的版本,但是你的链接器似乎找到并使用了你的openssl库的旧版本。

EVP_MD_CTX_new() in 1.1.0已在1.0.x中替代EVP_MD_CTX_create()

EVP_MD_CTX_free() in 1.1.0已在1.0.x中替换EVP_MD_CTX_destroy()

您可能会尝试使用这些函数的旧版本,或者确保链接器确实使用了openssl库的> = 1.1.0版本。

+0

谢谢你的想法。 但有趣的是,如果我使用EVP_MD_CTX_create()或EVP_MD_CTX_destroy(),链接器的输出为_new和_free。 明天我会尝试链接器的规范。 –

+0

@ K.Math这也可以解释:当使用openssl 1.1.0的头文件时,会有兼容的宏, '#define EVP_MD_CTX_create()EVP_MD_CTX_new()'。所以你似乎使用1.1.0头文件,但链接到1.0.x库。 – Ctx

+0

谢谢。添加-L 后,它工作。 –

The version is 1.1.0f. I try to run the example code of the openssl.org site ...

I installed and reinstalled OpenSSL 2 times from the website by compiling it ...

我相信OpenSSL 1.1.0安装到/usr/local/ssl。标头位于/usr/local/ssl/include,库位于/usr/local/ssl/lib。您需要编译和链接有:

gcc -I /usr/local/ssl digest_example.c -Wl,-L,/usr/local/lib -lssl -lcrypto 

事实上,因为Linux路径他妈的k'd起来,你需要使您链接到运行时的正确的库添加一个RPATH(未编译时) 。所以,你真的需要以下因为Linux仍然不能正确后30年左右得到它:

gcc -I /usr/local/ssl digest_example.c -Wl,-rpath,/usr/local/lib -Wl,-L,/usr/local/lib -lssl -lcrypto 

你仍然需要获得库的顺序正确的,因为LD是单通连接。

您的命令与系统的OpenSSL版本1.0.2相关联。

gcc digest_example.c -lcrypto -lssl 

然而,库的顺序是错误的。图书馆应该被称为-lssl -lcrypto