C++ 使用 Crypto++ 生成 SHA256 哈希,使用字符串作为输入和输出?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5930056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:12:04  来源:igfitidea点击:

Generating a SHA256 hash with Crypto++, using a string as input and output?

c++hashstdstringsha256crypto++

提问by Doug

I need an example of how to use Crypto++ to generate a SHA256 hash from a std::string and output a std::string. I can't seem to figure it out. Everything I've tried gives me invalid output.

我需要一个示例,说明如何使用 Crypto++ 从 std::string 生成 SHA256 哈希并输出 std::string。我似乎无法弄清楚。我尝试过的一切都给了我无效的输出。

Here's the new code after interjay's answer:

这是 interjay 回答后的新代码:

string SHA256(string data)
{
    byte const* pbData = (byte*) data.data();
    unsigned int nDataLen = data.size();
    byte abDigest[CryptoPP::SHA256::DIGESTSIZE];

    CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen);

    return string((char*)abDigest);
}

The output for SHA256("A"); is

SHA256("A") 的输出;是

enter image description here

在此处输入图片说明

How can I turn this into a readable format?

如何将其转换为可读格式?

Thanks to interjay's answer I was able to generate the final hash.

感谢 interjay 的回答,我能够生成最终的哈希值。

采纳答案by interjay

This line will give the wrong results:

这一行将给出错误的结果:

unsigned int nDataLen = sizeof(pbData);

It will always give you the size of a pointer. What you want instead is data.size().

它总是会给你一个指针的大小。你想要的是data.size().

Also, you don't need this part:

此外,您不需要这部分:

if(!CryptoPP::SHA256().VerifyDigest(abDigest, pbData, nDataLen))
{
    return SHA256(data);
}

It should always verify correctly, since you just calculated the digest based on the same data. And if it didn't, you'd go into infinite recursion.

它应该始终正确验证,因为您只是根据相同的数据计算了摘要。如果没有,您将进入无限递归。

To get readable output, you can convert it to hex. Here's an example for MD5 from the Crypto++ Wiki, it should work for you if you replace MD5 with SHA256:

要获得可读的输出,您可以将其转换为十六进制。这是来自Crypto++ Wiki 的MD5 示例,如果您将 MD5 替换为 SHA256,它应该对您有用:

CryptoPP::MD5 hash;
byte digest[ CryptoPP::MD5::DIGESTSIZE ];
std::string message = "abcdefghijklmnopqrstuvwxyz";

hash.CalculateDigest( digest, (byte*) message.c_str(), message.length() );

CryptoPP::HexEncoder encoder;
std::string output;
encoder.Attach( new CryptoPP::StringSink( output ) );
encoder.Put( digest, sizeof(digest) );
encoder.MessageEnd();

std::cout << output << std::endl;  

回答by Rooke

This outputs a base64 string using the CryptoPP::Base64Encoder:

这将使用以下命令输出一个 base64 字符串CryptoPP::Base64Encoder

#include "sha.h"
#include "filters.h"
#include "base64.h"

std::string SHA256HashString(std::string aString){
    std::string digest;
    CryptoPP::SHA256 hash;

    CryptoPP::StringSource foo(aString, true,
    new CryptoPP::HashFilter(hash,
      new CryptoPP::Base64Encoder (
         new CryptoPP::StringSink(digest))));

    return digest;
}

回答by cryptoboy

Your code will expect a null-terminated string from the buffer you supply to the string constructor! Which means the result will almost certainly be wrong.

您的代码需要从您提供给字符串构造函数的缓冲区中得到一个以空字符结尾的字符串!这意味着结果几乎肯定是错误的。

To enforce the digest size and, use the following instead:

要强制执行摘要大小,请改用以下内容:

return std::string((char*)abDigest, CryptoPP::SHA256::DIGESTSIZE);

return std::string((char*)abDigest, CryptoPP::SHA256::DIGESTSIZE);

Also with respect to printing it the following correctly produces the test vector BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015ADfor the string "abc"

同样关于打印它,以下正确生成BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD字符串的测试向量"abc"

std::string string_to_hex(const std::string& input)
{
  static const char* const lut = "0123456789ABCDEF";
  size_t len = input.length();

  std::string output;
  output.reserve(2 * len);
  for (size_t i = 0; i < len; ++i)
  {
    const unsigned char c = input[i];
    output.push_back(lut[c >> 4]);
    output.push_back(lut[c & 15]);
  }
  return output;
}

std::string SHA256(std::string data)
{
  CryptoPP::byte const* pbData = (CryptoPP::byte*)data.data();
  unsigned int nDataLen = data.length();
  CryptoPP::byte abDigest[CryptoPP::SHA256::DIGESTSIZE];

  CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen);

  // return string((char*)abDigest);  -- BAD!!!
  return std::string((char*)abDigest, CryptoPP::SHA256::DIGESTSIZE);
}

void test_cryptopp() {
  std::cout << string_to_hex(SHA256("abc")) << std::endl;
}