摘要算法:AIX 5.3 使用 openssl 實現 md5 等

摘要算法:AIX 5.3 使用 openssl 實現 md5 等

環境:

$ uname -a
AIX aix68112 3 5 00F7CAA94C00

查看 openssl 庫:

$ ll /usr/lib/*ssl*
lrwxrwxrwx    1 root     system           41 Jul 24 2017  /usr/lib/libgsk7ssl_64.so -> /usr/opt/ibm/gsksa/lib64/libgsk7ssl_64.so
-r-xr-xr-x    1 root     system      8595301 May 19 02:09 /usr/lib/libssl.a
-r-xr-xr-x    1 root     system      3400639 May 19 02:09 /usr/lib/libssl_compat.a

注意:此處 openssl 在 AIX 5.3 中是以靜態庫形式存在的。

代碼:

$ cat main.c
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

int main(int argc, char *argv[])
{
        EVP_MD_CTX mdctx;
        const EVP_MD *md;
        unsigned char md_value[EVP_MAX_MD_SIZE];
        int md_len, i;

        OpenSSL_add_all_digests();

/*********************************************************************/
        char *algorithm = "md5";
        char *msg = "0123456789abcdef";
        md = EVP_get_digestbyname(algorithm);
        if(!md) {
                fprintf(stderr, "Unknown message digest %s\n", algorithm);
                exit(1);
        }

        EVP_MD_CTX_init(&mdctx);
        EVP_DigestInit_ex(&mdctx, md, NULL);
        EVP_DigestUpdate(&mdctx, msg, strlen(msg));
        EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
        EVP_MD_CTX_cleanup(&mdctx);

        for(i = 0; i < md_len; i++) {
                fprintf(stdout, "%02x", md_value[i]);
        }
        fprintf(stdout, "\n");

        return 0;
}

編譯 && 鏈接:

$ xlc -o main main.c -lssl
"main.c", line 26.46: 1506-280 (W) Function argument assignment between types "unsigned int*" and "int*" is not allowed.
ld: 0711-317 ERROR: Undefined symbol: .OpenSSL_add_all_digests
ld: 0711-317 ERROR: Undefined symbol: .EVP_get_digestbyname
ld: 0711-317 ERROR: Undefined symbol: .EVP_MD_CTX_init
ld: 0711-317 ERROR: Undefined symbol: .EVP_DigestInit_ex
ld: 0711-317 ERROR: Undefined symbol: .EVP_DigestUpdate
ld: 0711-317 ERROR: Undefined symbol: .EVP_DigestFinal_ex
ld: 0711-317 ERROR: Undefined symbol: .EVP_MD_CTX_cleanup
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.

問題:找不到符號定義(函數)。

嘗試從 libssl.a 中查找 EVP_get_digestbyname 的符號定義:

$ nm /usr/lib/libssl.a  | grep OpenSSL_add_all_digests
$

確實沒有此函數的全局符號定義。

AIX 5.3 中的 openssl 命令是如何工作的呢?

$ ldd `which openssl`
/usr/bin/openssl needs:
         /usr/lib/libc.a(shr.o)
         /usr/lib/libcrypto.a(libcrypto.so.1.0.0)
         /usr/lib/libssl.a(libssl.so.1.0.0)
         /unix
         /usr/lib/libcrypt.a(shr.o)

查看到一個特殊的庫:libcrypto.a。

嘗試添加 -lcrypto 庫進行編譯鏈接:

$ xlc -o main main.c -lssl -lcrypto
"main.c", line 26.46: 1506-280 (W) Function argument assignment between types "unsigned int*" and "int*" is not allowed.
$ ./main
4032af8d61035123906e58e067140cc5

編譯、鏈接、執行成功!

我們看看 libcrypto.a 庫是否有 OpenSSL_add_all_digests 符號定義:

$ nm /usr/lib/libcrypto.a | grep OpenSSL_add_all_digests
.OpenSSL_add_all_digests T   269522904
OpenSSL_add_all_digests D   536987800          12
.OpenSSL_add_all_digests T   269522904
OpenSSL_add_all_digests D   536987800          12
.OpenSSL_add_all_digests T   269125248
OpenSSL_add_all_digests D   536979844          12
.OpenSSL_add_all_digests T   269522904
OpenSSL_add_all_digests D   536987800          12

既然 libssl.a 中沒有此函數定義,而 libcrypto.a 中有此函數定義,嘗試單獨使用 libcrypto.a 鏈接:

$ xlc -o main main.c -lcrypto
"main.c", line 26.46: 1506-280 (W) Function argument assignment between types "unsigned int*" and "int*" is not allowed.
$ ./main
4032af8d61035123906e58e067140cc5

OK!!!


AIX 5.3 中使用 openssl 實現相關算法時在鏈接處需要指明 libcrypto.a 靜態庫。否則將找不到符號定義。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章