libgcrypt-1.10.2编程-计算摘要


使用libgcrypt计算摘要

libgcrypt编程计算摘要的方式有2种,一种可用来计算小数据的摘要,如字符串; 一种可用来计算大数据的摘要,如文件、网络字节流等

下面的代码示例中用到了 cppcodec 工具库,用于将计算的摘要结果转换成hex十六进制字符串或者base64字符串

使用 libgcrypt 库有一个方便之处就是它已经支持国密算法 sm2、sm3、sm4,不过按照国密标准带公钥计算sm3摘要这种可能没支持,我暂时没找到官网源代码中有这样的示例或说明,这个就得自己封装了


一、计算少量数据摘要

计算少量数据摘要步骤较为简单,一般直接调用 gcry_md_hash_buffer API就行,参数中有一个指针参数作为输出参数。API gcry_md_get_algo_dlen 用于获取指定摘要算法的摘要长度,一般使用枚举 gcry_md_algos 作为摘要算法名,如
GCRY_MD_SHA1 GCRY_MD_SHA256 GCRY_MD_SM3

void calcWay1(const char* buffer) {
    int msg_len = strlen(buffer);
    int mdLen = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
    uint8_t* hash = new uint8_t[mdLen];
    gcry_md_hash_buffer(GCRY_MD_SHA1, hash, buffer, msg_len);

    std::cout << "十六进制输出: " << hex::encode(hash, mdLen) << std::endl;
    std::cout << "base64输出: " << base64::encode(hash, mdLen) << std::endl;
    delete[] hash;
}

二、计算大量数据摘要

与 OpenSSL 库作类比,计算大量数据摘要步骤一般固定如下

  1. gcry_md_open 创建摘要计算处理器(上下文),这一点跟 OpenSSL 类似
  2. gcry_md_write 多次调用传入数据,如读取文件时,循环读取数据到缓存中,将缓存作为参数循环传入该函数
  3. gcry_md_read 获取计算的摘要值
  4. gcry_md_close 关闭摘要计算处理器
void calcWay2(const char *buffer) {
    gcry_md_algos md_algos = GCRY_MD_SHA1;
    int mdLen = gcry_md_get_algo_dlen(md_algos);

    gcry_md_hd_t hd = nullptr;
    gcry_error_t error = gcry_md_open(&hd, md_algos, 0);
    if (error != GPG_ERR_NO_ERROR) {
        fprintf(stderr, "gcry_md_open error\n");
        exit(1);
    }

    // 多次调用 gcry_md_write 函数,适用于大数据摘要计算
    size_t length = strlen(buffer);
    gcry_md_write(hd, buffer, length);
    gcry_md_write(hd, buffer, length);

    uint8_t* hash = gcry_md_read(hd, md_algos);
    std::cout << "十六进制输出: " << hex::encode(hash, mdLen) << std::endl;
    std::cout << "base64输出: " << base64::encode(hash, mdLen) << std::endl;
    gcry_md_close(hd);
}

在main函数中调用

cppcodec 见文章开头说明,是 github 上一个基于C++的 hex、base32、base64 转换工具

#include <gcrypt.h>
#include <iostream>
#include "cppcodec/base64_rfc4648.hpp"
#include "cppcodec/hex_upper.hpp"

using base64 = cppcodec::base64_rfc4648;
using hex = cppcodec::hex_upper;

void calcWay1(const char *buffer);
void calcWay2(const char *buffer);

int main(int argc, char** argv){
    if (argc < 3) {
        fprintf(stderr, "Usage: %s arg1 arg2\n", argv[0]);
        exit(1);
    }

    int way = atoi(argv[1]);
    if (way == 1) {
        calcWay1(argv[2]);
    } else if (way == 2) {
        calcWay2(argv[2]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值