首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >返回SHA256值的OpenSSL问题- C++

返回SHA256值的OpenSSL问题- C++
EN

Stack Overflow用户
提问于 2021-02-25 02:49:02
回答 1查看 104关注 0票数 1

我需要用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是错误的……

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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!!
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66357065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档