我需要用OpenSSL生成SHA256值的帮助。我有代码:
typedef unsigned char byte;
int generateSHA256() {
unsigned char temp[SHA256_DIGEST_LENGTH];
char buf[SHA256_DIGEST_LENGTH * 2];
const unsigned char *charToGenerate;
size_t lenCharToGenerate;
memset(buf, 0x0, SHA256_DIGEST_LENGTH * 2);
memset(temp, 0x0, SHA256_DIGEST_LENGTH);
SHA256(charToGenerate, lenCharToGenerate, temp);
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
sprintf_s((char *)&(buf[i * 2]), sizeof(buf) / 2, "%02x", temp[i]);
}
return 0;
}
返回的SHA256值不正确。
当此代码更改为返回SHA1时,则值是正确的。代码完全相同:
typedef unsigned char byte;
int generateSHA() {
unsigned char temp[SHA_DIGEST_LENGTH];
char buf[SHA_DIGEST_LENGTH * 2];
const unsigned char *charToGenerate;
size_t lenCharToGenerate;
memset(buf, 0x0, SHA_DIGEST_LENGTH * 2);
memset(temp, 0x0, SHA_DIGEST_LENGTH);
SHA1(charToGenerate, lenCharToGenerate, temp);
for (int i = 0; i < SHA_DIGEST_LENGTH; i++) {
sprintf_s((char *)&(buf[i * 2]), sizeof(buf) / 2, "%02x", temp[i]);
}
return 0;
}
有没有人知道缺少了什么,这样代码才能返回正确的SHA256值?
我不知道为什么它适用于SHA1,但对于SHA256是错误的……
发布于 2021-02-25 04:04:05
如果这样做的目的是生成一个包含sha字节的asci十六进制字符串(在任何一种情况下),那么您的sprintf_s
循环(a)在说谎时,目标缓冲区会越来越小,因为你不断地重复传递
sizeof(buf)/2
是一个谎言,(b)在最后一次写入时调用未定义的行为,当您包括一个终止符时,这将产生一个三个字符的输出,但此时您距离缓冲区结束只有两个字节)。
如果你打算用C++来做这件事,那就开始使用标准库吧;它在很多方面都派上了用场。此外,使用EVP系列(所有现代OpenSSL应用程序都应该使用它,如果它们有任何意义的话;从长远来看,它会变得更容易)。
// standard includes
#include
#include
#include
#include
#include
#include
// openssl libraries
#include
#include
namespace OpenSSL
{
struct Delete
{
void operator()(EVP_MD_CTX *p) const
{
EVP_MD_CTX_free(p);
}
};
template
using Ptr = std::unique_ptr;
}
using EVP_MD_CTX_ptr = OpenSSL::Ptr;
// generic MD digest runner
std::string generateDigest(const void *src, size_t slen, const EVP_MD* digest)
{
unsigned int mdlen = EVP_MD_size(digest);
std::vector md(mdlen);
EVP_MD_CTX_ptr ctx(EVP_MD_CTX_new());
EVP_DigestInit(ctx.get(), digest);
EVP_DigestUpdate(ctx.get(), src, slen);
EVP_DigestFinal(ctx.get(), md.data(), &mdlen);
// build output string
static const char halpha[] = "0123456789abcdef";
std::string result;
result.reserve(mdlen * 2);
for (auto b : md)
{
result.push_back(halpha[(b >> 4) & 0xF]);
result.push_back(halpha[b & 0xF]);
}
return result;
}
std::string generateSHA1(const void *src, std::size_t slen)
{
return generateDigest(src, slen, EVP_sha1());
}
std::string generateSHA256(const void *src, std::size_t slen)
{
return generateDigest(src, slen, EVP_sha256());
}
int main()
{
OpenSSL_add_all_digests();
OpenSSL_add_all_algorithms();
static const char msg[] = "The quick brown fox jumps over the lazy dog";
static const char kat1[] = "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12";
static const char kat256[] = "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592";
auto s = generateSHA1(msg, sizeof(msg)-1);
if (s != kat1)
{
std::cout << "SHA1 FAIL\n";
return EXIT_FAILURE;
}
s = generateSHA256(msg, sizeof(msg)-1);
if (s != kat256)
{
std::cout << "SHA256 FAIL\n";
return EXIT_FAILURE;
}
std::cout << "Success!!\n";
return EXIT_SUCCESS;
}
输出
Success!!
https://stackoverflow.com/questions/66357065
复制相似问题