Skip to content
This repository has been archived by the owner on Jan 10, 2021. It is now read-only.

Commit

Permalink
Merge pull request #31 from Glusk2/hmac
Browse files Browse the repository at this point in the history
#30 Added a HMAC implementation.
  • Loading branch information
Glusk2 committed Mar 30, 2018
2 parents a9aee66 + 2c425b3 commit 56d5f7b
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.github.glusk2.wse.common.crypto.util.hashing;

import javax.xml.bind.DatatypeConverter;

public interface DigestArgument {

byte[] bytes();
Expand All @@ -8,6 +10,10 @@ final class BYTES implements DigestArgument {

private final byte[] bytes;

public BYTES(String hex) {
this(DatatypeConverter.parseHexBinary(hex));
}

public BYTES(byte... bytes) {
this.bytes = bytes;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.github.glusk2.wse.common.crypto.util.hashing;

public final class Hmac implements DigestArgument {
private static final byte OPAD_BYTE = 0x5c;
private static final byte IPAD_BYTE = 0x36;
public static final int DEFAULT_BLOCK_SIZE = 64;

private final IntermediateDigest hmac;

public Hmac(
ImmutableMessageDigest imd,
DigestArgument key,
DigestArgument message
) {
this(imd, key, DEFAULT_BLOCK_SIZE, message);
}

public Hmac(
ImmutableMessageDigest imd,
DigestArgument key,
int blockSize,
DigestArgument message
) {
this(
imd,
new XoredArguments(
new HmacKey(imd, key, blockSize),
new ValueExpansion(OPAD_BYTE, blockSize)
),
new XoredArguments(
new HmacKey(imd, key, blockSize),
new ValueExpansion(IPAD_BYTE, blockSize)
),
message
);
}

public Hmac(
ImmutableMessageDigest imd,
DigestArgument opad,
DigestArgument ipad,
DigestArgument message
) {
this(
new IntermediateDigest(
imd,
opad,
new IntermediateDigest(
imd,
ipad,
message
)
)
);
}

public Hmac(IntermediateDigest hmac) {
this.hmac = hmac;
}

@Override
public byte[] bytes() {
return hmac.bytes();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.github.glusk2.wse.common.crypto.util.hashing;

import java.util.Arrays;

public final class HmacKey implements DigestArgument {

private final ImmutableMessageDigest imd;
private final DigestArgument key;
private final int blockSize;

public HmacKey(
ImmutableMessageDigest imd,
DigestArgument key,
int blockSize
) {
this.imd = imd;
this.key = key;
this.blockSize = blockSize;
}

@Override
public byte[] bytes() {
byte[] keyBytes = key.bytes();
if (keyBytes.length <= blockSize) {
return Arrays.copyOf(keyBytes, blockSize);
}
return imd.update(key).digest();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.github.glusk2.wse.common.crypto.util.hashing;

import java.util.Arrays;

public final class ValueExpansion implements DigestArgument {

private final byte value;
private final int length;

public ValueExpansion(byte value, int length) {
this.value = value;
this.length = length;
}

@Override
public byte[] bytes() {
byte[] result = new byte[length];
Arrays.fill(result, value);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.github.glusk2.wse.common.crypto.util.hashing;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import org.junit.Test;

public class HmacTest {

@Test
public void testOneRFC2104() {
ImmutableMessageDigest imd = null;
try {
imd = new ImdSimpleCopy(MessageDigest.getInstance("MD5"));
} catch (NoSuchAlgorithmException e) {
fail(e.getMessage());
}
assertTrue(
"Digest doesn't match the test vector.",
Arrays.equals(
new DigestArgument.BYTES(
"9294727a3638bb1c13f48ef8158bfc9d"
).bytes(),
new Hmac(
imd,
new ValueExpansion((byte) 0x0b, 16),
new StringArgument("Hi There")
).bytes()
)
);
}

@Test
public void testTwoRFC2104() {
ImmutableMessageDigest imd = null;
try {
imd = new ImdSimpleCopy(MessageDigest.getInstance("MD5"));
} catch (NoSuchAlgorithmException e) {
fail(e.getMessage());
}
assertTrue(
"Digest doesn't match the test vector.",
Arrays.equals(
new DigestArgument.BYTES(
"750c783e6ab0b503eaa86e310a5db738"
).bytes(),
new Hmac(
imd,
new StringArgument("Jefe"),
new StringArgument("what do ya want for nothing?")
).bytes()
)
);
}

@Test
public void testThreeRFC2104() {
ImmutableMessageDigest imd = null;
try {
imd = new ImdSimpleCopy(MessageDigest.getInstance("MD5"));
} catch (NoSuchAlgorithmException e) {
fail(e.getMessage());
}
assertTrue(
"Digest doesn't match the test vector.",
Arrays.equals(
new DigestArgument.BYTES(
"56be34521d144c88dbb8c733f0e8b3f6"
).bytes(),
new Hmac(
imd,
new ValueExpansion((byte) 0xaa, 16),
new ValueExpansion((byte) 0xdd, 50)
).bytes()
)
);
}
}

0 comments on commit 56d5f7b

Please sign in to comment.