调用openssl库使用HMAC_SHA256算法小结

本文介绍了一种使用HMAC算法对用户信息进行加密的方法,并提供了在Linux环境下实现的具体步骤与源代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       本人在撰写代码时遇到需要对一些用户信息进行加密处理的情形。经过查阅资料,当然主要是报大腿成功解决了。下面做一些记录总结。

参考文章:

https://blog.youkuaiyun.com/yasi_xi/article/details/9066003

https://en.wikipedia.org/wiki/HMAC

环境完善:

该版本需要调用libssl.so.1.0.0,编译、运行时需要拷贝该库文件到lib目录。 检查存在 lib/libssl.so.1.0.0 及 libssl.so文件链接,如:

lrwxrwxrwx 1 ****** users      15 8月   2 21:01 libssl.so -> libssl.so.1.0.0

-rwxr-xr-x 1 ****** users  478235 8月   2 21:01 libssl.so.1.0.0

代码编写:

在需要调用加密的.c文件里添加头文件#include "./openssl/hmac.h"并定义宏MAX_INFOR_LENGTH

在该.c文件的同层新建文件夹openssl,并从openssl官网下载的openssl1.0.0里的一些相关头文件拷贝进去,多拷贝一些也没问题。

在软件初始化的时候把秘钥添加进去。秘钥可以做成配置项,以便动态的修改。

Strcpy(gConfig.mackey, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")

设计以下三个函数,调用最后一个函数可以对内容进行加密。由于这是linux下的库,所以添加添加了条件编译的判断代码。

函数一:HMAC加密核心处理函数

#ifndef _WIN32
int HmacEncode(const char * input, unsigned int inlen, unsigned char * output, unsigned int* outlen,const char * algo)
{
    unsigned char mdstr[MAX_INFOR_LENGTH+1] = {0};
    unsigned int mdlen = MAX_INFOR_LENGTH+1, keylen, tmplen;
    EVP_MD * engine = NULL;
    HMAC_CTX ctx;

    if(strcasecmp("sha512", algo) == 0) {
        engine = EVP_sha512();
    }
    else if(strcasecmp("sha256", algo) == 0) {
        engine = EVP_sha256();
    }
    else if(strcasecmp("sha1", algo) == 0) {
        engine = EVP_sha1();
    }
    else if(strcasecmp("md5", algo) == 0) {
        engine = EVP_md5();
    }
    else if(strcasecmp("sha224", algo) == 0) {
        engine = EVP_sha224();
    }
    else if(strcasecmp("sha384", algo) == 0) {
        engine = EVP_sha384();
    }
    else if(strcasecmp("sha", algo) == 0) {
        engine = EVP_sha();
    }
    else if(strcasecmp("md2", algo) == 0) {
        engine = EVP_md2();
    }
    else {
        LOG_printf( "Algorithm %s is not supported by this program!", algo);
        return -1;
    }

    keylen = strlen((char *)gConfig.mackey);
    // 加密
    HMAC_CTX_init(&ctx);
    HMAC_Init_ex(&ctx, (char *)gConfig.mackey, keylen, engine, NULL);
    HMAC_Update(&ctx, (unsigned char*)input, inlen);
    HMAC_Final(&ctx, mdstr, &mdlen);

    // 转换成16进制字符串
    tmplen = *outlen;
    if (*outlen == 0)
    {
        *outlen = inlen;
        tmplen = MAX_SENS_INFOR_LEN;
    }
    sagBinToHex(output, tmplen, mdstr, mdlen, 1);

    // 后释放,防止ssl版本不对mdstr被清除
    HMAC_CTX_cleanup(&ctx);

    *outlen = strlen((char *)output);
LOG_printf("inlen[%d] mdlen[%d] outlen[%d] output[%s]", inlen, mdlen, *outlen, output);
    // 长度保持与输入一致
    if (inlen < *outlen)
    {
        output[inlen] = '\0';
        *outlen = inlen;
    }
LOG_printf("input[%s] inlen[%d] mdlen[%d] outlen[%d] output[%s]", input, inlen, mdlen, *outlen, output);
    return 0;
}
#endif

函数二:转换成16进制字符串函数

unsigned char *	sagBinToHex(unsigned char * out, unsigned intoutLen, const unsigned char * in, unsigned intinLen, unsigned char flag)
{
	char	buf[4];
	UINT32	i, prnLen, sepLen;
	
	out[0] = 0;
	prnLen = 0;
	if (flag == 1)
		sepLen = 2;
	else
		sepLen = 3;
	
	for (i = 0; i < inLen; ++ i)
	{
		sprintf(buf, "%02x", (unsigned char)in[i]);
		if (flag == 2)	// 以空格分隔
			strcpy(char *)buf, " ");
		
		if (prnLen + sepLen >= outLen)
		{
			out[prnLen] = '\0';
			return out;
		}
		prnLen += sepLen;
		strcat((char *)out, buf);
	}
	
	*(out + 3 * inLen) = '\0';
	return out;
}

函数三:代码中直接调用的函数

int  HmacShaEncrypt(unsigned char * out, unsigned intoutLen, const unsigned char * in, unsigned char * hmac_type)
{
#ifndef _WIN32
    if (gConfig.mackey[0] != '\0')
    {
        unsigned char strmd[MAX_INFOR_LENGTH+1];
        unsigned int mdlen = MAX_INFOR_LENGTH+1;

        HmacEncode(in, strlen(in), strmd, &mdlen,hmac_type);
        if (mdlen < MAX_INFOR_LENGTH)
            strmd[mdlen] = '\0';
        else
            strmd[MAX_INFOR_LENGTH] = '\0';

        strcpy(out, strmd);
        return out;
    }
#endif
}

编译时makefile里需要添加LDLIBS=……-lssl……

调试自测日志:

test sensitive  result:f1474d23b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓翔仔

星光很亮,我们永远胸怀梦想

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值