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

相关推荐
我要出家当道士3 天前
OpenSSL的一些使用案例
linux·c·加解密·openssl·通讯加密
丁总学Java11 天前
Redis-数据类型-Hash
redis·oracle·哈希算法·hash
银氨溶液14 天前
Map集合之HashMap细说
java·开发语言·后端·面试题·集合·hashmap·hash
「QT(C++)开发工程师」1 个月前
ubuntu20.04 安装OpenSSL 1.0.2o (借助腾讯AI完全OK)
linux·qt·ubuntu·openssl
一条代码鱼1 个月前
升级最新版openssh-9.7p1及openssl-1.1.1h详细步骤及常见问题总结
linux·openssl·openssh
寒冬小子1 个月前
每天50个JAVA八股~(十七)
java·开发语言·学习·面试·hash
jimbo_lee1 个月前
openssl 常用命令demo
开发语言·python·openssl
Anakki1 个月前
【MySQL精通之路】SQL优化(1)-查询优化(4)-Hash联接查询
数据库·sql·mysql·hash·联接
xing.yu.CTF1 个月前
攻防世界-bug题目详解
开发语言·网络安全·php·bug·web·hash·xff
IT WorryFree1 个月前
离线安装gcc,openssh9.7,zlib,perl,openssl
开发语言·perl·openssl·openssh·zlib