lrleon
lrleon

Reputation: 2648

What is wrong with this sha 256 function?

I'm starting to use crypto++ lib and maybe I have some misconceptions.

I don't realize why the following code produces a bad sha 256

# include <string>
# include <iostream>
# include "cryptopp/cryptlib.h"
# include <cryptopp/sha.h>
# include <cryptopp/hex.h>

using namespace std;

string sha256_hex(const string & str)
{
  byte digest[CryptoPP::SHA256::DIGESTSIZE];
  CryptoPP::SHA256().CalculateDigest(digest, (byte*) &str[0], str.size());

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

  return ret;
}

int main(int argc, char *argv[])
{
  auto sha256 = sha256_hex(argv[1]);
  cout << "str     = " << argv[1] << endl
       << "sha 256 = " << sha256_hex(sha256) << endl;

  return 0;
}

The following command

./test-sha256 hello

produces the following output

str     = hello
sha 256 = DD9F20FF4F1DD817C567DE6C16915DC0A731A4DF51088F55CEF4CD2F89CF9620

However according to this online calculator enter link description here, the correct sha 256 for "hello" would be 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824.

So my question is what am I doing wrong?

I have an additional question: how and when the memory used by the StringSink object should be freed?

Thanks in advance

Upvotes: 1

Views: 1674

Answers (3)

Felix Dombek
Felix Dombek

Reputation: 14372

As for the second part of the question:

In the Crypto++ Pipelining system, filters and sinks are owned by the object they are attached to. They are automatically deleted by the destructor of that object.

And from "Important Usage Notes" in ReadMe.txt:

If a constructor for A takes a pointer to an object B (except primitive types such as int and char), then A owns B and will delete B at A's destruction. If a constructor for A takes a reference to an object B, then the caller retains ownership of B and should not destroy it until A no longer needs it.

Upvotes: 2

TonyK
TonyK

Reputation: 17114

Aren't you computing the hash of the hash here? You call sha256_hex twice, once with argv[1] as argument, and once with sha256 itself as argument.

Upvotes: 5

Ajay
Ajay

Reputation: 18431

Most probably, I see the problem is here:

CryptoPP::SHA256().CalculateDigest(digest, (byte*) &str[0], str.size());

You better pass str.c_str(). Use debugger to see what exactly is being passed - does it translate to hello ?

Upvotes: 1

Related Questions