JAVA中的HMAC-SHA1

时间:2013-11-16 13:16:53

标签: java hmacsha1

我正在尝试使用Java创建一个代码来获取带密钥的消息的HMAC-SHA1,结果必须与UBUNTU中的以下openssl命令行匹配: openssl dgst -sha1 -hmac key-in-hex filename.fil

我在Java中有以下代码:

private static MessageDigest md;
private static byte[] XorKeyIpad, XorKeyOpad;

private static final byte ipad = 0x36;
private static final byte opad = 0x5c;
private static final byte maxsize = 64;

public static void HMAC_SHA1(String msg, String keyString) throws NoSuchAlgorithmException, UnsupportedEncodingException {

    int i;
    String keyHex = toHex(keyString);
    byte[] keyByte = keyHex.getBytes();
    md = MessageDigest.getInstance("SHA-1");

    //Verify if the Key have the right size;
    if (keyByte.length > maxsize) {
        keyByte = md.digest(keyByte);
        md.reset();
    }
    System.out.println("KeyByte: " + keyByte + " Length: " + keyByte.length);

    //XOR between Key and ipad;
    XorKeyIpad = new byte[maxsize];
    for (i = 0; i < keyByte.length; i++) {
        XorKeyIpad[i] = (byte) (keyByte[i] ^ ipad);
    }
    System.out.println("XorKeyIpad: " + XorKeyIpad + "  Ipad: " + ipad);
    md.update(XorKeyIpad);
    XorKeyIpad = md.digest(XorKeyIpad);       


    //Concat the XOR between Key and ipad with the message;
    String concatXorKIM = concatByteString(XorKeyIpad, msg);


    //SHA1 of the concat the XOR between Key and ipad with the message(which i call X);
    md.update(concatXorKIM.getBytes());
    byte[] hashConcatXorKIM = md.digest();
    md.reset();


    //XOR between Key and opad(which i call Y);
    XorKeyOpad = new byte[maxsize];
    for (i = 0; i < keyByte.length; i++) {
        XorKeyOpad[i] = (byte) (keyByte[i] ^ opad);
    }

    //Concat between X and Y;
    byte[] concatHashXorKI_XorKO = concatByteByte(hashConcatXorKIM, XorKeyOpad);

    //SHA1 of the variable concatHashXorKI_XorKO
    md.update(concatHashXorKI_XorKO);
    byte[] hmac = md.digest();
    md.reset();
}


public static String toHex(String arg) throws UnsupportedEncodingException {
    return String.format("%040x", new BigInteger(1, arg.getBytes("UTF-8")));
}

public static String concatByteString(final byte[] bytes, final String str) {
    final StringBuilder sb = new StringBuilder();
    for (byte b : bytes) {
        sb.append(b);
    }
    sb.append(str);
    return sb.toString();
}

public static byte[] concatByteByte(final byte[] byteOne, final byte[] byteTwo) {
    byte[] concatBytes = new byte[byteOne.length + byteTwo.length];
    System.arraycopy(byteOne, 0, concatBytes, 0, byteOne.length);
    System.arraycopy(byteTwo, 0, concatBytes, byteOne.length, byteTwo.length);

    return concatBytes;
}

final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for (int j = 0; j < bytes.length; j++) {
        v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}`

两个结果不同,这意味着我做错了。

有人可以帮助我吗?

提前致谢。

2 个答案:

答案 0 :(得分:0)

你可以试试这个:

@Grapes(
    @Grab(group='commons-codec', module='commons-codec', version='1.10')
)

import org.apache.commons.codec.digest.HmacUtils

HmacUtils.hmacSha1Hex(key.bytes, message.bytes)

答案 1 :(得分:0)

试试这个:

private static final byte zero = 0x00;
XorKeyOpad = new byte[maxsize];
for (i = 0; i < maxsize; i++) 
{
    XorKeyOpad[i] = (byte) ((keyByte[i] ^ opad):(zero ^ opad));
}

密钥长度必须与maxsize相同。 如果它更小,则必须用零填充。