John Bokma

Perl Base64 encoded HMAC SHA256 signatures and padding

April 27, 2017

Today, while porting a Python implementation of a web based API to Perl I ran into a minor issue: the Perl module I used to generate a Base64 encoded HMAC SHA256 signature does not pad the Base64 result in such a way that the length of the result is always a multiple of 4.

While this is by convention and clearly documented it is also easy to forget, which today, I did.

For comparison, this is an example in Python:

import hmac, hashlib

secret  = 'ZHL15U78FoMFwgPqo190tBT0y'
message = 'The message'
h = hmac.new(secret, message, hashlib.sha256).digest()
signature = h.encode('base64').strip('\n')
print signature

The reported signature is:

mCCB7JtlyBjLGTKkxQdFxQK6ySZT4gEGvA56SstO7h0=

And this is the same example in Perl, which requires the padding to be added explicitly:

#!/usr/bin/perl

use strict;
use warnings;

use Digest::SHA 'hmac_sha256_base64';

my $secret  = 'ZHL15U78FoMFwgPqo190tBT0y';
my $message = 'The message';
my $signature = hmac_sha256_base64( $message, $secret );

# Base64 must be padded with =
while ( length( $signature ) % 4 ) {
    $signature .= '=';
}

print "$signature\n";

home - blog - email

I am a freelance Perl programmer for hire, download my up-to-date resume (PDF).