欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

调用 OpenSSL 1.1.1 计算 SM3 杂凑值的一个简单示例

程序员文章站 2022-03-16 08:42:25
...

    在前面的博文《Windows上使用VS 2010编译OpenSSL 1.1.1-pre6》中介绍了如何在 Windows 平台上编译 OpenSSL 1.1.1, 在这个版本中增加了对国密 SM2、SM3、SM4 算法的支持,本文介绍一下如何调用它计算 SM3 杂凑值。

    在编译好的 OpenSSL 1.1.1 库文件中,并没有对外部提供单独的计算 SM3 杂凑值的函数。计算各种杂凑函数,都需要通过调用 EVP 相关函数来完成。下面对调用 EVP 计算 SM3 杂凑值的过程进行了一下简单封装,分为三个文件给出示例代码:

1) sm3hash.h

/**************************************************
* File name: sm3hash.h
* Author: HAN Wei
* Author's blog: http://blog.csdn.net/henter/
* Date: June 18th, 2018
* Description: declare a sm3 hash calculation function
**************************************************/ 

#ifndef HEADER_C_FILE_SM3_HASH_H
  #define HEADER_C_FILE_SM3_HASH_H

#ifdef  __cplusplus
  extern "C" {
#endif

int sm3_hash(const unsigned char *message, size_t len, unsigned char *hash, unsigned int *hash_len);

#ifdef  __cplusplus
  }
#endif

#endif  /* end of HEADER_C_FILE_SM3_HASH_H */

2) sm3hash.c

/**************************************************
* File name: sm3hash.c
* Author: HAN Wei
* Author's blog: http://blog.csdn.net/henter/
* Date: June 18th, 2018
* Description: implement a sm3 hash calculation function
**************************************************/ 

#include "openssl/evp.h"
#include "sm3hash.h"

int sm3_hash(const unsigned char *message, size_t len, unsigned char *hash, unsigned int *hash_len)
{
    EVP_MD_CTX *md_ctx;
    const EVP_MD *md;

    md = EVP_sm3();
    md_ctx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(md_ctx, md, NULL);
    EVP_DigestUpdate(md_ctx, message, len);
    EVP_DigestFinal_ex(md_ctx, hash, hash_len);
    EVP_MD_CTX_free(md_ctx);
    return 0;
}

3) demo.c

/**************************************************
* File name: demo.c
* Author: HAN Wei
* Author's blog: http://blog.csdn.net/henter/
* Date: June 18th, 2018
* Description: This program demonstrates how to calculate SM3 hash
    by invoking OpenSSL v1.1.1. Sample data used here are excerpted
    from GM/T 0004 "SM3 cryptographic hash algorithm".
**************************************************/

#include <stdio.h>
#include <string.h>
#include "sm3hash.h"

int main(void)
{
	const unsigned char sample1[] = {'a', 'b', 'c', 0};
	unsigned int sample1_len = strlen((char *)sample1);
	const unsigned char sample2[] = {0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64,
                                         0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64,
                                         0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64,
                                         0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64,
                                         0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64,
                                         0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64,
                                         0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64,
                                         0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64};
	unsigned int sample2_len = sizeof(sample2);
	unsigned char hash_value[64];
	unsigned int i, hash_len;

	sm3_hash(sample1, sample1_len, hash_value, &hash_len);
	printf("raw data: %s\n", sample1);
	printf("hash length: %d bytes.\n", hash_len);
	printf("hash value:\n");
	for (i = 0; i < hash_len; i++)
	{
	    printf("0x%x  ", hash_value[i]);
	}
	printf("\n\n");

	sm3_hash(sample2, sample2_len, hash_value, &hash_len);
	printf("raw data:\n");
	for (i = 0; i < sample2_len; i++)
	{
	    printf("0x%x  ", sample2[i]);
	}
	printf("\n");
	printf("hash length: %d bytes.\n", hash_len);
	printf("hash value:\n");
	for (i = 0; i < hash_len; i++)
	{
	    printf("0x%x  ", hash_value[i]);
	}
	printf("\n");

	return 0;
}

    如果是在 Windows 平台上使用 Visual Studio 编译以上程序,在项目的“属性页”中,“属性配置”->“C/C++”->“附加包含目录”中要设置 OpenSSL 头文件所在目录,比如对于 32 位的 OpenSSL,目录可能为:C:\Program Files (x86)\OpenSSL\include 。注意在设置后括号相关字符会有变化,有可能会显示成:C:\Program Files %28x86%29\OpenSSL\include ,但不影响使用。

   “属性配置”->“链接器”->“常规”->“附加库目录”要设置 OpenSSL 库文件所在的目录,比如对于 32 位的 OpenSSL,目录可能为:C:\Program Files (x86)\OpenSSL\lib 。注意在设置后括号相关字符会有变化,有可能会显示成:C:\Program Files %28x86%29\OpenSSL\lib ,但不影响使用。

   “属性配置”->“链接器”->“输入”->“附加依赖项”要设置 OpenSSL 库文件名,比如:libcrypto.lib 。

    在运行程序时,要将 OpenSSL 的动态库文件 libcrypto-1_1.dll (如果编译出的是32位的exe程序,要用到这个32位库文件)或 libcrypto-1_1-x64.dll(如果编译出的是64位的exe程序,要用到这个64位库文件)拷贝到 Windows 系统目录下,或拷贝到编译出的 exe 文件所在目录下,只有这样程序才能正常运行。运行结果如下图:

调用 OpenSSL 1.1.1 计算 SM3 杂凑值的一个简单示例

相关标签: OpenSSL