> 文章列表 > openssl之EVP实现哈希(md5,sha256,sm3)

openssl之EVP实现哈希(md5,sha256,sm3)

openssl之EVP实现哈希(md5,sha256,sm3)

目录

一、环境说明

二、功能说明

三、EVP接口说明

四、使用实例

4.1 MD5算法实现实例。

4.2 sha256算法实现实例。

4.3 sm3算法实现实例。

五、源码地址


一、环境说明

操作系统:linux(debian)

开发工具:Qt creator 4.8.2

Qt版本:5.11.3.45-1

openssl版本:openssl-3.1.0

二、功能说明

1、使用openssl的EVP接口开发对数据进行hash。算法包括:md5、sha256、sm3

2、使用openssl的EVP接口开发对文件进行hash。算法包括:md5、sha256、sm3

三、EVP接口说明

使用EVP的接口有以下几个:EVP_MD_CTX_new,EVP_DigestInit_ex,EVP_DigestUpdate,EVP_DigestFinal_ex,EVP_MD_CTX_free

函数名称 函数说明
EVP_MD_CTX 摘要上下文对象结构
EVP_MD_CTX * EVP_MD_CTX_new(void) 创建摘要上下文对象
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type) 初始化摘要上下文,type为摘要算法抽象集合。
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);

向摘要计算的海棉结构输入一段数据,多次输入表示数据累计。

成功返回1,失败返回0

int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); 生成最终摘要,输出摘要值和长度。
成功返回1,失败返回0。
int EVP_MD_CTX_free(EVP_MD_CTX *ctx) 释放摘要上下文对象

四、使用实例

4.1 MD5算法实现实例。

实现了对数据的MD5散列,以及对文件内容MD5散列。

#include "encytion_md5.h"
#include <QtDebug>
#include <QFile>
#include <QDataStream>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
#include "tools.h"
EncytionMD5::EncytionMD5(QObject *) {}QString EncytionMD5::EncytonData(QString string)
{qInfo() << "EncytionMD5 " << string;unsigned int len = 0;EVP_MD_CTX *ctx = EVP_MD_CTX_new();EVP_DigestInit_ex(ctx, EVP_md5(), nullptr);// hash计算EVP_DigestUpdate(ctx, string.toStdString().c_str(),string.toStdString().length());unsigned char result[MD5_DIGEST_LENGTH] = {};EVP_DigestFinal_ex(ctx, result, &len);QString res = Tools::CharToHex(result, len);EVP_MD_CTX_free(ctx);return res;
}QString EncytionMD5::EncytonFile(QString inFilePath)
{qInfo() << "EncytionMD5 EncytonFile" << inFilePath;unsigned int len = 0;EVP_MD_CTX *ctx = EVP_MD_CTX_new();EVP_DigestInit_ex(ctx, EVP_md5(), nullptr);FILE *fp = nullptr;fp = fopen(inFilePath.toStdString().c_str(), "rb+");if (nullptr == fp) {return "";}char szDataBuff[MD5_DIGEST_LENGTH];unsigned long nLineLen;unsigned long a = 1;while (!feof(fp)) {memset(szDataBuff, 0x00, sizeof(szDataBuff));nLineLen = fread(szDataBuff, a,static_cast<unsigned long>(MD5_DIGEST_LENGTH), fp);if (nLineLen) {EVP_DigestUpdate(ctx, szDataBuff, static_cast<int>(nLineLen));}}fclose(fp);unsigned char result[MD5_DIGEST_LENGTH] = {};EVP_DigestFinal_ex(ctx, result, &len);EVP_MD_CTX_free(ctx);QString res = Tools::CharToHex(result, len);return res;
}

4.2 sha256算法实现实例。

实现了对数据的sha256散列,以及对文件内容sha256散列。

#include "encytion_sha256.h"
#include <QtDebug>
#include <QtDebug>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include "tools.h"
EncytionSha256::EncytionSha256(QObject *) {}
// 数据加密
QString EncytionSha256::EncytonData(QString string)
{qInfo() << "EncytionSha256 " << string;unsigned int len = 0;EVP_MD_CTX *ctx = EVP_MD_CTX_new();EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr);// hash计算EVP_DigestUpdate(ctx, string.toStdString().c_str(),string.toStdString().length());unsigned char result[SHA256_DIGEST_LENGTH] = {};EVP_DigestFinal_ex(ctx, result, &len);QString res = Tools::CharToHex(result, len);EVP_MD_CTX_free(ctx);return res;
}
// 文件加密,返回加密内容
QString EncytionSha256::EncytonFile(QString inFilePath)
{qInfo() << "EncytionSha256 EncytonFile" << inFilePath;unsigned int len = 0;EVP_MD_CTX *ctx = EVP_MD_CTX_new();EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr);FILE *fp = nullptr;fp = fopen(inFilePath.toStdString().c_str(), "rb+");if (nullptr == fp) {return "";}char szDataBuff[SHA256_DIGEST_LENGTH];unsigned long nLineLen;unsigned long a = 1;while (!feof(fp)) {memset(szDataBuff, 0x00, sizeof(szDataBuff));nLineLen = fread(szDataBuff, a,static_cast<unsigned long>(SHA256_DIGEST_LENGTH), fp);if (nLineLen) {EVP_DigestUpdate(ctx, szDataBuff, static_cast<int>(nLineLen));}}fclose(fp);unsigned char result[SHA256_DIGEST_LENGTH] = {};EVP_DigestFinal_ex(ctx, result, &len);EVP_MD_CTX_free(ctx);QString res = Tools::CharToHex(result, len);return res;
}

4.3 sm3算法实现实例。

实现了对数据的sm3散列,以及对文件内容sm3散列。

#include "encytion_sm3.h"
#include <QtDebug>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/sm3.h>
#include "tools.h"
EncytionSM3::EncytionSM3(QObject *) {}QString EncytionSM3::EncytonData(QString string)
{qInfo() << "EncytionSM3 " << string;unsigned int len = 0;EVP_MD_CTX *ctx = EVP_MD_CTX_new();EVP_DigestInit_ex(ctx, EVP_sm3(), nullptr);// hash计算EVP_DigestUpdate(ctx, string.toStdString().c_str(),string.toStdString().length());unsigned char result[SM3_DIGEST_LENGTH] = {};EVP_DigestFinal_ex(ctx, result, &len);//    EVP_MD_CTX_init(&ctx);QString res = Tools::CharToHex(result, len);EVP_MD_CTX_free(ctx);return res;
}QString EncytionSM3::EncytonFile(QString inFilePath)
{qInfo() << "EncytionSha256 EncytonFile" << inFilePath;unsigned int len = 0;EVP_MD_CTX *ctx = EVP_MD_CTX_new();EVP_DigestInit_ex(ctx, EVP_sm3(), nullptr);FILE *fp = nullptr;fp = fopen(inFilePath.toStdString().c_str(), "rb+");if (nullptr == fp) {return "";}char szDataBuff[SM3_DIGEST_LENGTH];unsigned long nLineLen;unsigned long a = 1;while (!feof(fp)) {memset(szDataBuff, 0x00, sizeof(szDataBuff));nLineLen = fread(szDataBuff, a,static_cast<unsigned long>(SM3_DIGEST_LENGTH), fp);if (nLineLen) {EVP_DigestUpdate(ctx, szDataBuff, static_cast<int>(nLineLen));}}fclose(fp);unsigned char result[SM3_DIGEST_LENGTH] = {};EVP_DigestFinal_ex(ctx, result, &len);EVP_MD_CTX_free(ctx);QString res = Tools::CharToHex(result, len);return res;
}

五、源码地址

GitHub - arv000/cipher: linux操作系统,使用openssl实现加密解密功能。