openssl3.2 - exp - class warp for sha3-512

文章目录

    • [openssl3.2 - exp - class warp for sha3-512](#openssl3.2 - exp - class warp for sha3-512)
    • 概述
    • 笔记
    • 调用方代码
    • [子类 - cipher_sha3_512.h](#子类 - cipher_sha3_512.h)
    • [子类 - cipher_sha3_512.cpp](#子类 - cipher_sha3_512.cpp)
    • [基类 - cipher_md_base.h](#基类 - cipher_md_base.h)
    • [基类 - cipher_md_base.cpp](#基类 - cipher_md_base.cpp)
    • 备注
    • END

openssl3.2 - exp - class warp for sha3-512

概述

前面实验整了一个对buffer进行sha3-512算hash的函数。

实际用的时候,要对几个buffer连续做hash. 前面封装的统一做hash的函数不适用。

重新封装了一个类,只要在类的生命周期中,就可以随时对连续的buffer(可能不在一个函数中)做hash的update.

笔记

调用方代码

c 复制代码
bool CPeFileCheck::calc_hash_SHA3_512()
{
    bool b_rc = false;
    CCipherSha3_512 hash;

    do {
        if (!hash.begin())
        {
            break;
        }

		// 如果buffer不在一个函数中,将hash的指针传给那些函数做hash.update
        if (!hash.update(this->m_pu8_map_file, this->m_u32_file_size))
        {
            break;
        }

        if (!hash.end())
        {
            break;
        }

        m_digest_length = hash.get_md_len();
        if (m_digest_length > sizeof(m_ary_digest_value))
        {
            break;
        }

        memcpy(m_ary_digest_value, hash.get_md(), hash.get_md_len());
        b_rc = true;
    } while (false);

    return b_rc;
}

子类 - cipher_sha3_512.h

c 复制代码
//! \file cipher_sha3_512.h

#ifndef __CIPHER_SHA3_512_H__
#define __CIPHER_SHA3_512_H__

#include "cipher_md_base.h"


class CCipherSha3_512 : public CCipherMdBase
{
public:
	CCipherSha3_512();
	virtual ~CCipherSha3_512();
};

#endif // #ifndef __CIPHER_SHA3_512_H__

子类 - cipher_sha3_512.cpp

c 复制代码
//! \file cipher_sha3_512.cpp

#include "pch.h"
#include "cipher_sha3_512.h"

CCipherSha3_512::CCipherSha3_512()
{
	setCiphherName("SHA3-512");
}

CCipherSha3_512::~CCipherSha3_512()
{
}

基类 - cipher_md_base.h

c 复制代码
//! \file cipher_md_base.h

#ifndef __CIPHER_MD_BASE_H__
#define __CIPHER_MD_BASE_H__

#include <openssl/evp.h>
#include <string>

//! \ref https://blog.csdn.net/LostSpeed/article/details/135581192
class CCipherMdBase
{
public:
	CCipherMdBase();
	virtual ~CCipherMdBase();

	bool begin();
	bool update(uint8_t* pBuf, int lenBuf);
	bool end();

	unsigned int get_md_len() { return m_digest_length; }
	uint8_t* get_md() { return m_p_digest_value; }

	void setCiphherName(const char* pszNmae) { m_strCipherName = ((NULL != pszNmae) ? pszNmae : ""); }

private:
	void clear();

private:
	std::string m_strCipherName;

	OSSL_LIB_CTX* m_ossl_lib_ctx;
	EVP_MD* m_evp_md;
	EVP_MD_CTX* m_evp_md_ctx;

	unsigned int m_digest_length;
	uint8_t* m_p_digest_value;
};

#endif // #ifndef __CIPHER_MD_BASE_H__

基类 - cipher_md_base.cpp

c 复制代码
//! \file cipher_md_base.cpp

#include "pch.h"
#include "cipher_md_base.h"

CCipherMdBase::CCipherMdBase()
	: m_ossl_lib_ctx(NULL),
	m_evp_md(NULL),
	m_evp_md_ctx(NULL),
	m_digest_length(0),
	m_p_digest_value(NULL)
{

}

CCipherMdBase::~CCipherMdBase()
{
    clear();
}

void CCipherMdBase::clear()
{
    if (NULL != m_evp_md_ctx)
    {
        EVP_MD_CTX_free(m_evp_md_ctx);
        m_evp_md_ctx = NULL;
    }

    m_digest_length = 0;
    if (NULL != m_p_digest_value)
    {
        OPENSSL_free(m_p_digest_value);
        m_p_digest_value = NULL;
    }

    if (NULL != m_evp_md)
    {
        EVP_MD_free(m_evp_md);
        m_evp_md = NULL;
    }

    if (NULL != m_ossl_lib_ctx)
    {
        OSSL_LIB_CTX_free(m_ossl_lib_ctx);
        m_ossl_lib_ctx = NULL;
    }
}

bool CCipherMdBase::begin()
{
    bool b_rc = false;
    const char* _psz_option_properties = NULL;

    do {
        clear();

        m_ossl_lib_ctx = OSSL_LIB_CTX_new();
        if (NULL == m_ossl_lib_ctx) {
            // fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
            break;
        }

        /*
         * Fetch a message digest by name
         * The algorithm name is case insensitive.
         * See providers(7) for details about algorithm fetching
         */

        if (m_strCipherName.empty())
        {
            break;
        }

        m_evp_md = EVP_MD_fetch(m_ossl_lib_ctx, m_strCipherName.data(), _psz_option_properties);
        if (NULL == m_evp_md) {
            // fprintf(stderr, "EVP_MD_fetch could not find SHA3-512.");
            break;
        }

        /*
         * Make a message digest context to hold temporary state
         * during digest creation
         */
        m_evp_md_ctx = EVP_MD_CTX_new();
        if (NULL == m_evp_md_ctx) {
            // fprintf(stderr, "EVP_MD_CTX_new failed.\n");
            break;
        }

        /*
         * Initialize the message digest context to use the fetched
         * digest provider
         */
        if (EVP_DigestInit(m_evp_md_ctx, m_evp_md) != 1) {
            // fprintf(stderr, "EVP_DigestInit failed.\n");
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool CCipherMdBase::update(uint8_t* pBuf, int lenBuf)
{
    bool b_rc = false;

    do {
        if (EVP_DigestUpdate(m_evp_md_ctx, pBuf, lenBuf) != 1) {
            // fprintf(stderr, "EVP_DigestUpdate(hamlet_1) failed.\n");
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;

}

bool CCipherMdBase::end()
{
    bool b_rc = false;
    int digest_length = 0;

    do {

        /* Determine the length of the fetched digest type */
        m_digest_length = EVP_MD_get_size(m_evp_md);
        if (m_digest_length <= 0) {
            // fprintf(stderr, "EVP_MD_get_size returned invalid size.\n");
            break;
        }

        m_p_digest_value = (uint8_t*)OPENSSL_malloc(m_digest_length);
        if (NULL == m_p_digest_value) {
            // fprintf(stderr, "No memory.\n");
            break;
        }

        if (EVP_DigestFinal(m_evp_md_ctx, m_p_digest_value, &m_digest_length) != 1) {
            // fprintf(stderr, "EVP_DigestFinal() failed.\n");
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

备注

这个封装类用的很舒服。

如果要做其他种类的hash, 只需要继承一个子类,给定新的hash算法名称就行。

END

相关推荐
是罐装可乐2 天前
深入理解 Vue3 Router:三种路由模式的工作原理与实战应用
架构·vue·路由·history·hash·ssr·router
深耕AI11 天前
Win64OpenSSL-3_5_2.exe【安装步骤】
openssl
看那山瞧那水12 天前
DELPHI 利用OpenSSL实现加解密,证书(X.509)等功能
delphi·openssl
洋哥网络科技22 天前
openssl升级
openssl
Lazy Dave1 个月前
gmssl私钥文件格式
网络安全·ssl·openssl
沉在嵌入式的鱼2 个月前
RK3588移植Openssl库
linux·rk3588·openssl
黑屋里的马2 个月前
ssl相关命令生成证书
服务器·网络·ssl·openssl·gmssl
fangeqin2 个月前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
API开发3 个月前
苹果芯片macOS安装版Homebrew(亲测) ,一键安装node、python、vscode等,比绿色软件还干净、无污染
vscode·python·docker·nodejs·openssl·brew·homebrew
码农不惑3 个月前
Rust使用tokio(二)HTTPS相关
https·rust·web·openssl