2011-05-08 86 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; 
} 
相關問題