A class to implement the HMAC message authentication code, as described in
RFC 2104.
The definition of HMAC-X for a given message digest algorithm X depends
on that algorithm's internal block size, which is passed into the constructor
when this class is used directly. Normally, this class will be obtained
indirectly via the JCA API, e.g.
MessageDigest.getInstance("HMAC-SHA-1")
if SHA-1 is to be used as the digest algorithm.
The key can be set as a byte array using the "key" parameter. It is
not
reset after the MAC has been returned (this enables successive MACs using the
same key to be calculated efficiently). For example:
import java.security.Parameterized;
MessageDigest hmac = MessageDigest.getInstance("HMAC-SHA-1");
byte[] key = ..., input1 = ..., input2 = ...;
((Parameterized) mac).setParameter("key", key);
byte[] mac1 = hmac.digest(input1);
byte[] mac2 = hmac.digest(input2);
Parameters other than "key" are passed through to the MessageDigest object,
but this can only be done when the key is not set. An explicit call to
reset()
will 'unset' the key.
This implementation does not support truncation of the output MAC. If
truncation is desired, the caller should use only the relevant initial bits
of the output array.
Note that although this class implements
Cloneable, its
clone()
method will throw a
CloneNotSupportedException
if the underlying MessageDigest cannot be cloned. This should not be the
case for any of the Cryptix-supported digest algorithms.
HMAC is similar, but
not identical to the MAC used by Secure Sockets
Layer version 3. The JCA standard algorithm name of the variant used in SSL v3
is "SSL3MAC-X", for a message digest name X.
References:
- RFC 2104, HMAC: Keyed-Hashing for Message Authentication
- RFC 2202, Test Cases for HMAC-MD5 and HMAC-SHA-1
Copyright © 1997
Systemics Ltd on behalf of the
Cryptix Development Team.
All rights reserved.
$Revision: 1.4 $
clone
public Object clone()
throws CloneNotSupportedException
Returns a copy of this HMAC object.
engineDigest
protected byte[] engineDigest()
Calculates the final MAC.
RFC 2104 describes HMAC as follows:
The definition of HMAC requires a cryptographic hash function, which
we denote by H, and a secret key K. We assume H to be a cryptographic
hash function where data is hashed by iterating a basic compression
function on blocks of data. We denote by B the byte-length of such
blocks (B=64 for all the above mentioned examples of hash functions),
and by L the byte-length of hash outputs (L=16 for MD5, L=20 for
SHA-1). The authentication key K can be of any length up to B, the
block length of the hash function. Applications that use keys longer
than B bytes will first hash the key using H and then use the
resultant L byte string as the actual key to HMAC. In any case the
minimal recommended length for K is L bytes (as the hash output
length). See section 3 for more information on keys.
We define two fixed and different strings
ipad and
opad
as follows (the 'i' and 'o' are mnemonics for inner and outer):
ipad = the byte 0x36 repeated B times
opad = the byte 0x5C repeated B times.
To compute HMAC over the data 'text' we perform
H(K XOR opad, H(K XOR ipad, text))
Namely,
- append zeros to the end of K to create a B byte string
(e.g., if K is of length 20 bytes and B=64, then K will be
appended with 44 zero bytes 0x00)
- XOR (bitwise exclusive-OR) the B byte string computed in step
(1) with ipad
- append the stream of data 'text' to the B byte string resulting
from step (2)
- apply H to the stream generated in step (3)
- XOR (bitwise exclusive-OR) the B byte string computed in
step (1) with opad
- append the H result from step (4) to the B byte string
resulting from step (5)
- apply H to the stream generated in step (6) and output
the result
engineGetDigestLength
protected int engineGetDigestLength()
SPI: Returns the digest length in bytes.
engineGetParameter
protected Object engineGetParameter(String param)
throws InvalidParameterException
engineReset
protected void engineReset()
Resets this object disregarding any temporary data present at the
time of the invocation of this call.
engineSetParameter
protected void engineSetParameter(String param,
Object value)
throws InvalidParameterException
engineUpdate
protected void engineUpdate(byte input)
Continues an HMAC digest using the input byte.
engineUpdate
protected void engineUpdate(byte[] input,
int offset,
int len)
Hashes a byte array from a given offset for a specified length.
input
- byte array from which data is to be hashed.offset
- start index of bytes to hash in input.len
- number of bytes to hash.
getParameter
public Object getParameter(String param)
throws InvalidParameterException
Gets the value of the specified algorithm parameter.
This method supplies a general-purpose mechanism through which it
is possible to get the various parameters of this object. A uniform
algorithm-specific naming scheme for each parameter is desirable but
left unspecified at this time.
- getParameter in interface Parameterized
param
- the string name of the parameter.
- the object that represents the parameter value.
setParameter
public void setParameter(String param,
Object value)
throws InvalidParameterException
Sets the specified algorithm parameter to the specified value.
This method supplies a general-purpose mechanism through which it is
possible to set the various parameters of this object. A uniform
algorithm-specific naming scheme for each parameter is desirable but
left unspecified at this time.
- setParameter in interface Parameterized
param
- the string identifier of the parameter.value
- the parameter value.