使用 OpenSSL 和 C + + 生成 sha256

我希望使用 openssl 和 C + + 创建一个具有 sha256的 hash。我知道在 使用 OpenSSL 库在 C + + 中生成 SHA 散列有一个类似的帖子,但我正在寻找特别创建 sha256。

更新:

似乎是一个包含路径的问题。它找不到任何 OpenSSL 函数,即使我包含

#include "openssl/sha.h"

我在构建中包含了路径

-I/opt/ssl/include/ -L/opt/ssl/lib/ -lcrypto
172666 次浏览

我认为你只需要将 SHA1函数替换为 SHA256函数,并在你的文章中使用来自链接的 tatk 代码

我是这么做的:

void sha256_hash_string (unsigned char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65])
{
int i = 0;


for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
sprintf(outputBuffer + (i * 2), "%02x", hash[i]);
}


outputBuffer[64] = 0;
}




void sha256_string(char *string, char outputBuffer[65])
{
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, string, strlen(string));
SHA256_Final(hash, &sha256);
int i = 0;
for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
sprintf(outputBuffer + (i * 2), "%02x", hash[i]);
}
outputBuffer[64] = 0;
}


int sha256_file(char *path, char outputBuffer[65])
{
FILE *file = fopen(path, "rb");
if(!file) return -534;


unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
const int bufSize = 32768;
unsigned char *buffer = malloc(bufSize);
int bytesRead = 0;
if(!buffer) return ENOMEM;
while((bytesRead = fread(buffer, 1, bufSize, file)))
{
SHA256_Update(&sha256, buffer, bytesRead);
}
SHA256_Final(hash, &sha256);


sha256_hash_string(hash, outputBuffer);
fclose(file);
free(buffer);
return 0;
}

它的名字是这样的:

static unsigned char buffer[65];
sha256("string", buffer);
printf("%s\n", buffer);

一个更“ C + +”的版本

#include <iostream>
#include <sstream>


#include "openssl/sha.h"


using namespace std;


string to_hex(unsigned char s) {
stringstream ss;
ss << hex << (int) s;
return ss.str();
}


string sha256(string line) {
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, line.c_str(), line.length());
SHA256_Final(hash, &sha256);


string output = "";
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
output += to_hex(hash[i]);
}
return output;
}


int main() {
cout << sha256("hello, world") << endl;


return 0;
}

性病

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>


using namespace std;


#include <openssl/sha.h>
string sha256(const string str)
{
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, str.c_str(), str.size());
SHA256_Final(hash, &sha256);
stringstream ss;
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
ss << hex << setw(2) << setfill('0') << (int)hash[i];
}
return ss.str();
}


int main() {
cout << sha256("1234567890_1") << endl;
cout << sha256("1234567890_2") << endl;
cout << sha256("1234567890_3") << endl;
cout << sha256("1234567890_4") << endl;
return 0;
}

使用 OpenSSL 的 EVP 接口(以下是针对 OpenSSL 1.1的) :

#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <openssl/evp.h>


bool computeHash(const std::string& unhashed, std::string& hashed)
{
bool success = false;


EVP_MD_CTX* context = EVP_MD_CTX_new();


if(context != NULL)
{
if(EVP_DigestInit_ex(context, EVP_sha256(), NULL))
{
if(EVP_DigestUpdate(context, unhashed.c_str(), unhashed.length()))
{
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int lengthOfHash = 0;


if(EVP_DigestFinal_ex(context, hash, &lengthOfHash))
{
std::stringstream ss;
for(unsigned int i = 0; i < lengthOfHash; ++i)
{
ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
}


hashed = ss.str();
success = true;
}
}
}


EVP_MD_CTX_free(context);
}


return success;
}


int main(int, char**)
{
std::string pw1 = "password1", pw1hashed;
std::string pw2 = "password2", pw2hashed;
std::string pw3 = "password3", pw3hashed;
std::string pw4 = "password4", pw4hashed;


hashPassword(pw1, pw1hashed);
hashPassword(pw2, pw2hashed);
hashPassword(pw3, pw3hashed);
hashPassword(pw4, pw4hashed);


std::cout << pw1hashed << std::endl;
std::cout << pw2hashed << std::endl;
std::cout << pw3hashed << std::endl;
std::cout << pw4hashed << std::endl;


return 0;
}

这种更高级别接口的优点是,您只需将 EVP_sha256()调用与另一个摘要的函数(例如 EVP_sha512())交换,就可以使用不同的摘要。所以它增加了一些灵活性。

下面是我个人使用的函数——我只是从 sha-1哈希函数中派生出来的:

char *str2sha256( const char *str, int length ) {
int n;
SHA256_CTX c;
unsigned char digest[ SHA256_DIGEST_LENGTH ];
char *out = (char*) malloc( 33 );


SHA256_Init( &c );


while ( length > 0 ) {
if ( length > 512 ) SHA256_Update( &c, str, 512 );
else SHA256_Update( &c, str, length );


length -= 512;
str += 512;
}


SHA256_Final ( digest, &c );


for ( n = 0; n < SHA256_DIGEST_LENGTH; ++n )
snprintf( &( out[ n*2 ] ), 16*2, "%02x", (unsigned int) digest[ n ] );


return out;
}

如果要计算文件的 sha256散列..。

auto sha256 = [](std::string fname,
std::vector<unsigned char>& hash) -> bool {
std::unique_ptr<EVP_MD_CTX, void (*)(EVP_MD_CTX *)>
evpCtx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
EVP_DigestInit_ex(evpCtx.get(), EVP_sha256(), nullptr);


constexpr size_t buffer_size { 1 << 12 };
std::vector<char> buffer(buffer_size,'\0');


std::ifstream fp(fname, std::ios::binary);
if (!fp.is_open()) {
std::cerr << "Unable to open '" << fname << "'!\n";
return false;
}
while (fp.good()) {
fp.read(buffer.data(), buffer_size);
EVP_DigestUpdate (evpCtx.get(), buffer.data(), fp.gcount());
}
fp.close();


hash.resize(SHA256_DIGEST_LENGTH);
std::fill(hash.begin(), hash.end(), 0);
unsigned int len;
EVP_DigestFinal_ex (evpCtx.get(), hash.data(), &len);


return true;
};


...


std::vector<unsigned char> hash;
sha256("/etc/profile", hash);
std::stringstream out;
for (size_t i = 0; i < hash.size(); i++)
out << std::setfill('0') << std::setw(2)
<< std::hex << int(hash[i]);
std::string hashStr = out.str();
std::cout << hashStr << std::endl;
...
a3fe9f414586c0d3cacbe3b6920a09d8718e503bca22e23fef882203bf765065