使用SSL的crypto库产生SHA256摘要(Digest)

  • Post author:
  • Post category:其他


可以为数据或者文档产生SHA256摘要,它是一串256个二进制位(32个字节)的数据,比如

https://www.openssl.org/source/openssl-1.1.1s.tar.gz

这个文件的SHA256摘要是c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa 。SHA256是使用密码学里的hash(杂散)函数产生的。它可以验证原始数据是否被改动。因为 一、找到两个不同数据而它的SHA256摘要相同是不容易的;二、从SHA256摘要反推原始数据是不容易的。

SSL里包含密码库可以产生SHA256摘要。本文作个导航。

1 下载已编译的SSL库,参考:

C++ 开源密码库之OpenSSL的使用_Ning静致远的博客-CSDN博客_openssl库使用


我这里下载的是64位的release库

2 在vs2019创建一控制台程序,设定额外的包含目录为上面解压出来include,额外库目录为上面的lib目录。记得在源文件里加#pragma comment(lib,”libcrypto.lib”),在设定里将PATH加上dll(libcrypto-3-x64.dll)的路径。

还要在源码里加#pragma warning(disable : 4996)编译才能通过。下面是代码:

//GreateSHA256.cpp
#pragma warning(disable : 4996)
//https://blog.csdn.net/qq_39975542/article/details/122547129?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-122547129-blog-80004638.pc_relevant_3mothn_strategy_recovery&spm=1001.2101.3001.4242.2&utm_relevant_index=4
//https://codeleading.com/article/23094792584/

#pragma comment(lib,"libcrypto.lib")

#include<iostream>
#include<fstream>
#include<string>

using namespace std;

#include<openssl/sha.h>
string sha256(const string str)
{
    char buf[3];
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, str.c_str(), str.size());
    SHA256_Final(hash, &sha256);
    std::string NewString = "";
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        sprintf(buf, "%02x", hash[i]);
        NewString = NewString + buf;
    }
    return NewString;
}

string sha256_file(const string fname)
{
    char buf[3];
    unsigned char hash[SHA256_DIGEST_LENGTH];
    FILE* fp; 
    fp = fopen(fname.c_str(), "rb");
    fseek(fp, 0, SEEK_END);
    unsigned long Len = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    unsigned char* data = new unsigned char[Len];
    fread(data, 1, Len, fp);
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, data, Len);
    SHA256_Final(hash, &sha256);
    std::string NewString = "";
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        sprintf(buf, "%02x", hash[i]);
        NewString = NewString + buf;
    }
    delete[] data;
    return NewString;
}

int main() {
    std::string x = "hello world";
    cout << sha256(x) << endl;
    string sha256 = sha256_file("openssl-1.1.1s.tar.gz");
    ofstream ofs("openssl-1.1.1s.tar.gz.sha256.new");
    ofs << sha256 << endl;
    ofs.close();
    cout << sha256 << endl;
    return 0;
}

OpenSSL 3.0 之后推荐使用 evp 库,下面是 使用evp库的代码。

//https://blog.csdn.net/zahuopuboss/article/details/9629317

#pragma comment(lib,"libcrypto.lib")


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

#include <string>
#include <fstream>
#include <cstdio>
#include <iostream>

using namespace std;


string sha256_file_usingEvp(const string fname)
{
	unsigned char hash[SHA256_DIGEST_LENGTH];
	unsigned int L_hash = 0;
	FILE* fp;
	fopen_s( &fp, fname.c_str(), "rb");
	fseek(fp, 0, SEEK_END);
	unsigned long Len = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	unsigned char* data = new unsigned char[Len];
	fread(data, 1, Len, fp);
	fclose(fp);
	EVP_Digest( data, Len, hash, &L_hash, EVP_sha256(), NULL);

	char buf[3];
	std::string NewString = "";
	for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
	{
		sprintf_s(buf, "%02x", hash[i]);
		NewString = NewString + buf;
	}
	delete[] data;
	return NewString;
}


string sha256_file_usingEvp_ex(const string fname)
{
	unsigned char hash[SHA256_DIGEST_LENGTH];
	unsigned int L_hash = 0;
	FILE* fp;
	fopen_s(&fp, fname.c_str(), "rb");
	fseek(fp, 0, SEEK_END);
	unsigned long Len = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	unsigned char* data = new unsigned char[Len];
	fread(data, 1, Len, fp);
	fclose(fp);
	EVP_MD_CTX *evp = EVP_MD_CTX_new();
	EVP_DigestInit_ex( evp, EVP_sha256(), NULL);
	EVP_DigestUpdate(evp, data, Len);
	EVP_DigestFinal_ex( evp, hash, &L_hash);


	char buf[3];
	std::string NewString = "";
	for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
	{
		sprintf_s(buf, "%02x", hash[i]);
		NewString = NewString + buf;
	}
	delete[] data;
	EVP_MD_CTX_free(evp);
	return NewString;
}
 
int main()
{
	string sha256 = sha256_file_usingEvp("openssl-1.1.1s.tar.gz");
	ofstream ofs("openssl-1.1.1s.tar.gz.sha256.evp.new1");
	ofs << sha256 << endl;
	ofs.close();
	cout << sha256 << endl << endl ;

	sha256 = sha256_file_usingEvp_ex("openssl-1.1.1s.tar.gz");
	ofs.open("openssl-1.1.1s.tar.gz.sha256.evp.new2");
	ofs << sha256 << endl;
	ofs.close();
	cout << sha256 << endl << endl;
	return 0;
}



版权声明:本文为brooknew原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。