首页 > 编程语言 >openssl做HMAC实例(C++)----自测OK

openssl做HMAC实例(C++)----自测OK

时间:2023-11-20 11:47:02浏览次数:39  
标签:OK unsigned len openssl 算法 key 自测 data HMAC

摘自:https://blog.csdn.net/mijichui2153/article/details/104741460

1、HMAC简介
(1)MAC(Message Authentication Code,消息认证码算法),可以将其认为是含有秘钥的散列(Hash)函数算法;即兼容了MD和SHA算法,并在此基础上加上了秘钥。因此MAC算法也经常被称作HMAC算法。当然HMAC就是“基于Hash的消息认证码”英文(Hash-based Message Authentication Code)的缩写。我个人理解它主要包括两块:一个是信息摘要算法(MD/SHA等);另外就是秘钥。

1)HMAC基于的信息摘要算法。目前主要集合了MD和SHA两大系列消息摘要算法。其中MD系列的算法有HmacMD2、HmacMD4、HmacMD5三种算法;SHA系列的算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512五种算法。

2)秘钥。理论上密钥可以是任何长度,但是一般出于安全强度的考量不建议使用太短的秘钥。也就是说一般情况下要使用摘要算法计算密钥的摘要作为新的密钥。

(2)使用流程。你和对方共享了一个密钥K,你要发消息给对方;这个过程即要保证消息没有被篡改还要能够证明信息确实是你本人发送的。所以处理的方式是:在发送数据以前,HMAC算法对“数据块”+“约定的公钥”进行散列操作并将所生成的“摘要”附加在待发送的数据块中。当原数据块和摘要到达其目的地时,目的端也会使用HMAC算法对原数据块和公钥来生成本地摘要,如果两个摘要相匹配,那么就认为数据未被做任何篡改且消息为约定的对方本人发送。

(3)加深理解。

1)其实通过MD5、SHA1等哈希算法我们可以验证一段数据是否有效,方法就是对比该数据的哈希值。例如判断用户的口令(密码)是否正确我们用保存在数据库中的password_md5对比计算得到的md5(password),如果一致就认为用户输入的密码是正确的。

2)由于用户密码通常会设置的比较简单而且具有普遍性,如果黑客做了足够大的对照表实际上就很有可能反推出真实密码。为了防止黑客通过对照表反推到原始密码,通常在计算哈希的时候会增加一个salt以使得相同的输入(这里指不同用户的相同密码)也能达到不同的哈希(例如将每个用户的唯一id作为salt的一部分),这样就大大的增加了破解难度。

3)实际上我们可以把上面说的salt看做是一个“口令”,所以加salt的哈希就是:计算一段message的哈希时,根据不同的口令计算出不同的哈希。即,要验证哈希值必须同时提供口令。上面的这个思路实际上就是Hmac算法了,它通过一个标准算法,在计算哈希的过程中把key混入计算过程。和我们自定义的加salt算法不同,Hmac算法针对所有的哈希算法都通用,无论是MD5还是SHA-1。其实可以认为Hmac算法和我们自定义的加salt的哈希算法本质上就是一个东西。但是使用Hmac替代我们自己的salt算法可以使程序算法更标准话,也更安全。

2、实例程序(打包代码 这里 )

//HmacUtil.h
#ifndef __HMAC_UTIL_H__
#define __HMAC_UTIL_H__



#ifdef __cplusplus             //告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的
extern "C"{
#endif

string UTIL_hmac_encrypt_sha512(const unsigned char *key, unsigned int key_len, const unsigned char *data, unsigned int data_len);


#ifdef __cplusplus             //告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的
}
#endif

#endif /* __HMAC_UTIL_H__ */

 

 

 

#include <string>
using namespace std;

#include <openssl/hmac.h>
#include <string.h>
#include "platform_common.h"
#include "liblicense_log.h"
#include "Base64Util.h"
#include "HmacUtil.h"

#define print_ln(log_level, fmt, ...) do {printf("(%s|%d)" fmt "\r\n", __func__, __LINE__, ##__VA_ARGS__); fflush(stdout);} while(0)

#define DEBUG_HMAC (0)

static int _hmac_encrypt(string algo,
        const unsigned char *key, unsigned int key_len,
        const unsigned char *data, unsigned int data_len,
        unsigned char * &output, unsigned int &output_length)
{
    const EVP_MD *engine = NULL;

    if (NULL == key || 0 >= key_len || NULL == data || 0 >= data_len ) {
        print_ln(ERROR, "wrong parameter.");
        return -1;
    }

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

    output = (unsigned char*)malloc(EVP_MAX_MD_SIZE);

    /*---------------------------------
    这块应该是相对通用的计算流程了
    --------------------------------*/
    HMAC_CTX ctx;
    HMAC_CTX_init(&ctx);
    HMAC_Init_ex(&ctx, (const void *)key, key_len, engine, NULL);
    HMAC_Update(&ctx, data, data_len);

    HMAC_Final(&ctx, output, &output_length);
    HMAC_CTX_cleanup(&ctx);

    return 0;
}


/*****************************************************************

    hmac加密


    参数 : algorithm_name, 摘要算法名称, 示例"sha512"、"sha256"、"sha1"、"md5"、"sha224"、"sha384"
           key, 输入参数, 密码
           key_len, 输入参数, 密码字节个数
           data, 输入参数, 待加密数据
           data_len, 输入参数, 待加密数据字节个数

     return : 长度>0, 成功, 返回消息认证码的 base64 字符串
              长度=0, 失败

*****************************************************************/
static string UTIL_hmac_encrypt(string algorithm_name, const unsigned char *key, unsigned int key_len, const unsigned char *data, unsigned int data_len)
{
    unsigned char *mac = NULL;
    unsigned int mac_length = 0;
    int ret = 0;
    string hmac_base64 = "";

    ret = _hmac_encrypt(algorithm_name, key, key_len, data, data_len, mac, mac_length);
    if (0 != ret) {
        return "";
    }

    hmac_base64 = UTIL_base64_encode((const unsigned char *)mac, mac_length);

    free(mac);

    return hmac_base64;
}


/*****************************************************************

    hmac加密(sha512)


    参数 : key, 输入参数, 密码
           key_len, 输入参数, 密码字节个数
           data, 输入参数, 待加密数据
           data_len, 输入参数, 待加密数据字节个数

     return : 长度>0, 成功, 返回消息认证码的 base64 字符串
              长度=0, 失败

*****************************************************************/
string UTIL_hmac_encrypt_sha512(const unsigned char *key, unsigned int key_len, const unsigned char *data, unsigned int data_len)
{
    return UTIL_hmac_encrypt("sha512", key, key_len, data, data_len);
}

#if DEBUG_HMAC
int main(int argc, char * argv[])
{
    string data = "Hello, world!9843tefwiut4h8r9uhw4re9u0ijt4reuwfuvs09hiout4urewg8v9hur4"; // 待加密的数据
    char key[] = "secret_key508io4wre45yr"; // secret key
    string hmac_base64 = "";

    hmac_base64 = UTIL_hmac_encrypt("sha512", (const unsigned char *)key, strlen(key), (const unsigned char *)data.c_str(), data.length());

    if(0 < hmac_base64.length()) {
        print_ln(DEBUG, "Algorithm HMAC encode succeeded|%s|", hmac_base64.c_str());
    } else {
        print_ln(ERROR, "Algorithm HMAC encode failed!");
        return -1;
    }


    return 0;
}
#endif

 

标签:OK,unsigned,len,openssl,算法,key,自测,data,HMAC
From: https://www.cnblogs.com/LiuYanYGZ/p/17843588.html

相关文章

  • openssl做HMAC实例(C++)原文
    摘自:https://blog.csdn.net/mijichui2153/article/details/1047414601、HMAC简介(1)MAC(MessageAuthenticationCode,消息认证码算法),可以将其认为是含有秘钥的散列(Hash)函数算法;即兼容了MD和SHA算法,并在此基础上加上了秘钥。因此MAC算法也经常被称作HMAC算法。当然HMAC就是“基......
  • GreatSQL社区与Amazon、Facebook、Tencent共同被MySQL致谢
    一、来自MySQL官方的感谢在2023-10-25MySQL官方发布的8.2版本ReleaseNotes中,GreatSQL社区核心开发者RichardDang和HaoLu,分别收到了来自MySQL官方的贡献感谢,与Amazon、Facebook(Meta)、Tencent等一并出现在感谢清单中。详见:MySQL8.2ReleaseNotes/Chang......
  • Docker部署cook | 跟着我一起用NAS来学习做菜吧
    一、介绍该项目是疫情期间大佬开发者开发的,项目初衷是方便特殊时期隔离在家而材料有限的小伙伴,因此菜谱材料会尽量限制在特定范围内,但很多都是家常菜,并且你能搜到的每一种菜都配有完整的视频教学。就算拿到今天对于我这种不怎么会做菜的人来说,这个项目真的泰裤辣。二、搭建cook......
  • web03(过滤器,监听器,cookie)
    过滤器(Filter)作用:在访问到正式资源之前进行过滤(请求到达Servlet之前、Servlet处理之后以及响应返回客户端之前进行干预);解决中文乱码问题:publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,Servle......
  • cmd常用命令(十)nslookup
    nslookup查看默认dnsC:\Users\admin>nslookup默认服务器:UnKnownAddress:192.168.51.51nslookup-debug8.8.8.8C:\Users\admin>nslookup-debug8.8.8.8------------Gotanswer:HEADER:opcode=QUERY,id=1,rcode=NXDOMAINheaderflag......
  • 什么是 Microsoft Outlook 的 Addin
    Outlook的Addin,又被称为“Outlook插件”,是一种可以扩展和增强Outlook功能的软件工具。插件可以深度集成到Outlook用户界面中,并在用户需要时提供自定义的功能和服务。例如,一个插件可能会提供特定的电子邮件管理功能,如排序、标记、归档或者搜索,或者提供与第三方服务的集成,如......
  • nanomq 轻量快速的mqtt broker
    nanomq是emqx团队开源的iot边缘mqttbroker,有点是轻量,性能好,同时官方也提供了与Mosquitto对比的介绍nanomq很多功能上与emqx是类似的,包含了rule,自定义auth,gatway协议,基于关系型数据库的存储一张官方的集成玩法一些特点快速 相比mosquitto有10倍的提升轻量 比较小跨......
  • 【nest入门】[bug记录]在jupyter notebook中使用conda环境(linux)
    NEST在安装引导https://nest-simulator.readthedocs.io/en/stable/installation/user.html#user-install中提供了conda的方式,如下图所示:如上图中步骤第1步,进行了condacreate--namenest36-cconda-forgenest-simulator后,在jupyter中想要切换到所创建的名为ENVNAME的con......
  • OpenSSL - Certificate Generation
    WewillusetheOpenSSL(https://www.openssl.org/source/)tooltogenerateself-signedcertificates.Acertificateauthority(CA)isresponsibleforstoring,signing,and issuingdigitalcertificates.Thismeanswewillfirstgenerateaprivatekeyanda......
  • Linux下荣耀MagicBook的触控板被错误识别为鼠标的临时解决方案
    TL;DR安装软件包hid-tools,然后运行命令:sudohid-featureset-f300003$(sudohid-featurelist-devices|grepBLTP7853|awk-F:'{print$1}')问题现象荣耀MagicBook笔记本安装了汇顶的触控板,此触控板在Linux下被识别为鼠标,导致无法使用触控板手势等功能。该触控板......