web-dev-qa-db-ja.com

入力と出力として文字列を使用して、Crypto ++でSHA256ハッシュを生成しますか?

Crypto ++を使用してstd :: stringからSHA256ハッシュを生成し、std :: stringを出力する方法の例が必要です。私はそれを理解できないようです。私が試したすべては私に無効な出力を与えます。

インタージェイの答えの後の新しいコードは次のとおりです。

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

これを読み取り可能な形式に変換するにはどうすればよいですか?

インタージェイの答えのおかげで、私は最終的なハッシュを生成することができました。

19
Doug

この行は間違った結果をもたらします:

_unsigned int nDataLen = sizeof(pbData);
_

それは常にあなたにポインタのサイズを与えるでしょう。代わりに必要なのはdata.size()です。

また、この部分は必要ありません。

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

同じデータに基づいてダイジェストを計算しただけなので、常に正しく検証する必要があります。そうでなければ、無限再帰になります。

読み取り可能な出力を取得するには、16進数に変換します。 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;  
_
16
interjay

これは、CryptoPP::Base64Encoderを使用してbase64文字列を出力します。

#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;
}
17
Rooke

コードは、文字列コンストラクターに提供するバッファーからnullで終了する文字列を予期します。つまり、結果はほぼ間違いなく間違っているということです。

ダイジェストサイズを強制するには、代わりに以下を使用します。

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

また、それを印刷することに関して、以下はテストベクトルを正しく生成します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;
}
0
cryptoboy