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

相关推荐
沉在嵌入式的鱼15 天前
RK3588移植Openssl库
linux·rk3588·openssl
黑屋里的马18 天前
ssl相关命令生成证书
服务器·网络·ssl·openssl·gmssl
fangeqin1 个月前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
API开发1 个月前
苹果芯片macOS安装版Homebrew(亲测) ,一键安装node、python、vscode等,比绿色软件还干净、无污染
vscode·python·docker·nodejs·openssl·brew·homebrew
码农不惑2 个月前
Rust使用tokio(二)HTTPS相关
https·rust·web·openssl
liulilittle2 个月前
通过高级处理器硬件指令集AES-NI实现AES-256-CFB算法并通过OPENSSL加密验证算法正确性。
linux·服务器·c++·算法·安全·加密·openssl
liulilittle2 个月前
OpenSSL 的 AES-NI 支持机制
linux·运维·服务器·算法·加密·openssl·解密
liulilittle2 个月前
通过高级处理器硬件指令集AES-NI实现AES-256-CFB算法。
linux·服务器·c++·算法·安全·加密·openssl
花花少年2 个月前
Ubuntu系统下交叉编译openssl
openssl·交叉编译
Aric_Jones2 个月前
HashMap 的底层原理
java·eclipse·maven·hashmap·hash