How to calculate HMAC with SHA256 and base64-encoding

2,048 views
Skip to first unread message

Paul Crown

unread,
Dec 13, 2010, 8:20:24 PM12/13/10
to Crypto++ Users
Greetings,

I would like to incorporate the equivalent of the following php code
snippet in a c++ app. I have been experimenting and have learned how
to use a number of crypto++ functions. I have yet, however, to fully
wrap my mind around this snippet.

I think that I have just figured out that the term "SHA256" is used in
different respects, one as a hash method, and one as a message
encoding method. Which means that my c++ snippet is useless.

In summary, I want to calculate HMAC with SHA256 and base64-encoding
in c++, just like demonstrated in the php snippet below. Can you
please point me in the right direction?

Thank you.

Paul



Php code snippet:

// calculate HMAC with SHA256 and base64-encoding

$signature = base64_encode(hash_hmac("sha256", $string_to_sign,
$private_key, True));

c++ snippet:

const char *secretId=msg_to_sign.c_str();
int msg_len = strlen( secretId );

// sha256
CryptoPP::SHA256 sha256hash;
unsigned char hash[ sha256hash.DIGESTSIZE ];
memset( hash, 0x00, sha256hash.DIGESTSIZE );
sha256hash.CalculateDigest(hash, (byte*)secretId, msg_len); // use
libcrypt0++ library

// hmac
unsigned char hmac[ sha256hash.DIGESTSIZE ];
memset( hmac, 0x00, sha256hash.DIGESTSIZE );
CryptoPP::HMAC<CryptoPP::SHA256>((byte*)secretId,
msg_len).CalculateDigest(hmac, hash, sha256hash.DIGESTSIZE);

Paul Crown

unread,
Dec 14, 2010, 12:03:20 AM12/14/10
to Crypto++ Users
My next attempt is getting a little better. Now how to base64 encode?

const char *secretId=msg_to_sign.c_str();
int msg_len = strlen( secretId );

CryptoPP::SHA256 sha256hash;
unsigned char hmac[ sha256hash.DIGESTSIZE ];
memset( hmac, 0x00, sha256hash.DIGESTSIZE );
CryptoPP::HMAC<CryptoPP::SHA256>((byte*)privateId,
pri_len).CalculateDigest(hmac, (byte*)secretId, msg_len);

Thanks.

Paul

Da Co

unread,
Dec 14, 2010, 10:02:41 AM12/14/10
to Paul Crown, Crypto++ Users
http://www.codeproject.com/KB/security/hexencdec.aspx

--
You received this message because you are subscribed to the "Crypto++ Users" Google Group.
To unsubscribe, send an email to cryptopp-user...@googlegroups.com.
More information about Crypto++ and this group is available at http://www.cryptopp.com.

Da Co

unread,
Dec 14, 2010, 10:10:08 AM12/14/10
to Paul Crown, Crypto++ Users

Paul Crown

unread,
Dec 14, 2010, 9:58:56 PM12/14/10
to Crypto++ Users
Thank you. I'm still a little off. Anyone see where I am still not
right?

with the same inputs,
php output: RB7psloFMPq2Z4jg7MUo35DtY+32atMUImfIfTWlHxM=
c++ output:
646434695767556b7a494e593875424d4f6230573547775a7a6f5467787a6252

code:
const char *secretId=msg_to_sign.c_str();
int msg_len = strlen( secretId );
CryptoPP::SHA256 sha256hash;
int dwLen = sha256hash.DIGESTSIZE;
// hmac
unsigned char hmac[ dwLen ];
memset( hmac, 0x00, dwLen );
CryptoPP::HMAC<CryptoPP::SHA256>((byte*)privateId,
pri_len).CalculateDigest(hmac, (byte*)secretId, msg_len);
// base64
CryptoPP::Base64Encoder hexEncoder;
hexEncoder.Put(hmac,dwLen);
//hexEncoder.Close(); // Shaun Wilde in 2000 uses, but it no
longer exists?
hexEncoder.Get(hmac,dwLen*2);

char *out = (char *) malloc( sizeof(char) * ((dwLen*2)+1) );
char *p = out;
for( int i = 0; i < dwLen; i++, p += 2 ) {
snprintf ( p, 3, "%02x", hmac[i] );
}

On Dec 14, 9:10 am, Da Co <danel...@gmail.com> wrote:
> Also , thanks to Andrey V.http://andreyvitdev.blogspot.com/2005/10/crypto-usage-sample.html
>
> On Tue, Dec 14, 2010 at 10:02 AM, Da Co <danel...@gmail.com> wrote:
> >http://www.codeproject.com/KB/security/hexencdec.aspx
>

Paul Crown

unread,
Dec 18, 2010, 11:34:30 AM12/18/10
to Crypto++ Users
Greetings,

Thanks Da Co.

FINAL Solution:

The php code used by many online API's to sign a data request in which
the signature is hashed with HMAC_SHA256 and base64-encoded is
reproduced via the Crypto++ library as follows:

phpcode:
$signature = base64_encode(hash_hmac("sha256", $string_to_sign,
$private_key, True));

c++:
// private_key and string_to_sign are std::string; private_key_len
and string_to_sign_len are int;
// hmac with sha256
CryptoPP::SHA256 hash;
int dwLen = hash.DIGESTSIZE;
unsigned char hmac[ dwLen ];
memset( hmac, 0x00, dwLen );
CryptoPP::HMAC<CryptoPP::SHA256>((byte*)private_key,
private_key_len).CalculateDigest(hmac, (byte*)string_to_sign,
string_to_sign_len);
// base64
CryptoPP::Base64Encoder baseEncoder;
baseEncoder.Put(hmac,dwLen);
baseEncoder.MessageEnd();
baseEncoder.Get(hmac,dwLen*2);
// to string
stringstream s;
s << hmac;
std::string string_encoded = s.str();

Hindsight, makes it look very straightforward. Wrapping my mind
around what was to be accomplished was the difficult part.

Paul

Paul Crown

unread,
Dec 18, 2010, 11:37:48 AM12/18/10
to Crypto++ Users
Correction:

private_key and string_to_sign are both const char *

Paul
Reply all
Reply to author
Forward
0 new messages