2011-05-08 106 views
17

我需要一个如何使用Crypto ++从std :: string生成SHA256哈希并输出std :: string的示例。我似乎无法弄清楚。我试过的所有东西都会给我输出无效。使用Crypto ++生成SHA256哈希,使用字符串作为输入和输出?

这里的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); 
} 

的输出SHA256( “A”);是

enter image description here

我怎样才能转成可读的格式呢?

感谢interjay的回答,我能够生成最终的散列。

+7

欢迎堆栈溢出!在这里它不起作用;你必须展示你的尝试,然后我们会帮助你。 – 2011-05-08 20:17:10

+2

请不要删除已回答的部分问题。 – interjay 2011-05-08 20:45:53

+2

如果你不想帮忙,为什么要麻烦评论?这个问题显然是措辞和可以理解的,绝对值得回答,没有以前的尝试。在常见问题中没有任何地方表明,需要显示他们以前的尝试。 – 2011-05-08 20:49:35

回答

14

这条线将给出错误的结果:

unsigned int nDataLen = sizeof(pbData); 

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

而且,你不需要这个部分:

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

应该总是正确地验证,因为你刚才计算的摘要基于相同的数据。如果没有,你会进入无限递归。

要获得可读输出,可以将其转换为十六进制。下面是来自Crypto++ Wiki的MD5为例,它应该为你工作,如果你有SHA256替换MD5:

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; 
+0

好吧我做了这些改变,虽然它现在似乎每次都给我相同的输出,但输出却是随机奇怪字符的乱码。我怎样才能将其更改为可读格式? – Doug 2011-05-08 20:39:30

+0

@Doug看到我编辑的答案。 – interjay 2011-05-08 20:46:49

+0

应用您的示例给出了从const char *到const字节*转换错误。 '(byte *)message.c_str()'是正确的转换。 – EisenHeim 2015-09-11 09:49:41

16

此输出使用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; 
} 
+0

奇妙的是,我正在寻找一种方法来实现流水线操作! – Ethan 2016-04-11 23:55:49

+0

CryptoPP还使用[SIMD x64](https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions)指令加快速度。 – ahmd0 2017-07-13 07:39:28

0

您的代码将期待一个空从您提供给字符串构造函数的缓冲区中终止字符串!这意味着结果几乎肯定会出错。

为了执行摘要大小和,而是使用以下:

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

而且相对于印刷了下列正确地产生测试向量BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD的字符串​​

std::string string_to_hex(const std::string& input) 
{ 
    static const char* const lut = "ABCDEF"; 
    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; 
}