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

相关推荐
bsr19834 天前
前端路由的hash模式和history模式
前端·history·hash·路由模式
初级代码游戏4 天前
openssl 正确生成v3带SAN的证书
https·证书·ssl·openssl·tls·v3
初级代码游戏11 天前
openssl s_server源码剥离
https·ssl·openssl·tls·s_server
QC七哥12 天前
openssl在windows下的编译
windows·openssl·vs2022
乌南竹14 天前
六十九:基于openssl实战验证RSA
openssl
daqinzl14 天前
利用ffmpeg将视频转为m3u8并加密
ffmpeg·openssl·m3u8·加密 解密
CAir217 天前
openssl编译
windows·编译·openssl
迷茫运维路21 天前
Openssl1.1.1s rpm包构建与升级
运维·openssl·rpmbuild
lally.1 个月前
密码学课程实验作业
密码学·des·mac·命令行·hash·rsa
曹朋羽1 个月前
openssl 安装及使用
网络·openssl