Cryptography Reference
In-Depth Information
cessful attacks against the versions of HMAC based on these functions. Thus HMAC
still seems secure in practice, and even more so if a collision resistant hash function
is used.
5.6.5.2 HMAC in Maple
Next we develop a Maple implementation of HMAC, specifically HMAC-SHA-256,
based on the hash function previously implemented as
SHA256
. We will follow
Algorithm 5.4 but we are going to simplify the key processing step somewhat. Since
SHA-256 uses 512-bit (64-byte) input blocks, and key sizes 512 bits or less seem
perfectly adequate from a security point of view, we are going to consider only keys
up to this size. In fact, we will only allow 16, 24 or 32-byte keys (i.e., AES keys, with
the largest size being the preferred one for security reasons) since this seems sufficient
and, this way, we may use the Maple function
checkkey
(from Appendix A) for
key processing. In addition to
checkkey
we will also use
messagetobytes
and
bytestohexstring
, also from Appendix A, as well as the previous functions
BitXor
and, of course,
sha256
.
The function
HMAC
is given below. It takes three inputs: the key given either as a
list of bytes or as a hex string, the message given as a string, and a name which can
be either
file, text
or
hex
, with the last as default. In case
file
is specified,
the second argument should be the name of a file in the current directory or given
with the full path if the file is located elsewhere. The output is the MAC tag given in
hexadecimal.
> HMAC := proc(key, message, messagetype::name := hex)
local m, k, ipad, opad;
m := messagetobytes(message, messagetype);
k := checkkey(key);
k := [op(k), '$'(0, 64-nops(k))];
ipad := ['$'(54, 64)];
opad := ['$'(92, 64)];
m := sha256([op(zip(BitXor, k, ipad)), op(m)]);
bytestohexstring(sha256([op(zip(BitXor, k, opad)), op(m)]))
end proc:
Examples 5.3
We compute a couple of examples taken from [110]:
> HMAC("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
"Hi There", text);
"198a607eb44bfbc69903a0f1cf2bbdc5ba0aa3f3d9ae3c1c7a3b1696a0b68cf7"
> HMAC("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd\
cdcdcdcdcdcdcdcdcdcdcdcdcd");
"372efcf9b40b35c2115b1346903d2ef42fced46f0846e7257bb156d3d7b30d3f"
As mentioned, the fact that the hash function in HMAC acts as a black box makes
it easy to build variants of the preceding implementation, which we leave as an
exercise.