package org.bouncycastle.crypto.test;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTestResult;
import org.bouncycastle.util.test.Test;
import org.bouncycastle.util.test.TestResult;
/**
* MD5 HMac Test, test vectors from RFC 2202
*/
public class MD5HMacTest
implements Test
{
final static String[] keys = {
"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
"4a656665",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"0102030405060708090a0b0c0d0e0f10111213141516171819",
"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
};
final static String[] digests = {
"9294727a3638bb1c13f48ef8158bfc9d",
"750c783e6ab0b503eaa86e310a5db738",
"56be34521d144c88dbb8c733f0e8b3f6",
"697eaf0aca3a3aea3a75164746ffaa79",
"56461ef2342edc00f9bab995690efd4c",
"6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd",
"6f630fad67cda0ee1fb1f562db3aa53e"
};
final static String[] messages = {
"Hi There",
"what do ya want for nothing?",
"0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
"0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
"Test With Truncation",
"Test Using Larger Than Block-Size Key - Hash Key First",
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
};
public static boolean arraysEqual(byte[] a, byte[] b)
{
if (a == b) return true;
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++)
{
if (a[i] != b[i]) return false;
}
return true;
}
public String getName()
{
return "MD5HMac";
}
public TestResult perform()
{
HMac hmac = new HMac(new MD5Digest());
byte[] resBuf = new byte[hmac.getMacSize()];
for (int i = 0; i < messages.length; i++)
{
byte[] m = messages[i].getBytes();
if (messages[i].startsWith("0x"))
{
m = Hex.decode(messages[i].substring(2));
}
hmac.init(new KeyParameter(Hex.decode(keys[i])));
hmac.update(m, 0, m.length);
hmac.doFinal(resBuf, 0);
if (!arraysEqual(resBuf, Hex.decode(digests[i])))
{
return new SimpleTestResult(false, getName() + "Vector " + i + " failed");
}
}
// test reset
int vector = 0; // vector used for test
byte[] m = messages[vector].getBytes();
if (messages[vector].startsWith("0x"))
{
m = Hex.decode(messages[vector].substring(2));
}
hmac.init(new KeyParameter(Hex.decode(keys[vector])));
hmac.update(m, 0, m.length);
hmac.doFinal(resBuf, 0);
hmac.reset();
hmac.update(m, 0, m.length);
hmac.doFinal(resBuf, 0);
if (!arraysEqual(resBuf, Hex.decode(digests[vector])))
{
return new SimpleTestResult(false, getName() +
"Reset with vector " + vector + " failed");
}
return new SimpleTestResult(true, getName() + ": Okay");
}
public static void main(
String[] args)
{
MD5HMacTest test = new MD5HMacTest();
TestResult result = test.perform();
System.out.println(result);
}
}