Question Générer un hachage SHA256 avec Crypto ++, en utilisant une chaîne en entrée et en sortie?


J'ai besoin d'un exemple d'utilisation de Crypto ++ pour générer un hachage SHA256 à partir d'un std :: string et générer un std :: string. Je n'arrive pas à comprendre. Tout ce que j'ai essayé me donne une sortie invalide.

Voici le nouveau code après la réponse d'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);
}

La sortie pour SHA256 ("A"); est

enter image description here

Comment puis-je transformer cela en un format lisible?

Grâce à la réponse d'interjay, j'ai pu générer le hash final.


18
2018-05-08 20:14


origine


Réponses:


Cette ligne donnera les mauvais résultats:

unsigned int nDataLen = sizeof(pbData);

Il vous donnera toujours la taille d'un pointeur. Ce que vous voulez à la place est data.size().

De plus, vous n'avez pas besoin de cette partie:

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

Il devrait toujours vérifier correctement, puisque vous venez de calculer le résumé basé sur les mêmes données. Et si ce n’était pas le cas, vous iriez en récursion infinie.

Pour obtenir un résultat lisible, vous pouvez le convertir en hexadécimal. Voici un exemple pour MD5 du Crypto ++ Wiki, cela devrait fonctionner pour vous si vous remplacez MD5 par 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;  

15
2018-05-08 20:35



Cela génère une chaîne base64 en utilisant le 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;
}

16
2017-08-12 20:16



Votre code attendra une chaîne terminée par un caractère nul à partir du tampon que vous fournissez au constructeur de chaînes! Ce qui signifie que le résultat sera presque certainement faux.

Pour appliquer la taille de résumé et utilisez plutôt les éléments suivants:

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

Toujours en ce qui concerne l'impression, les éléments suivants produisent correctement le vecteur de test BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD pour la chaîne "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
2018-02-22 22:27