调用openssl库使用HMAC_SHA256算法小结

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

参考文章:

https://blog.csdn.net/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

 

你可能感兴趣的:(code,design,skills)