我正在尝试使用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);
}`
两个结果不同,这意味着我做错了。
有人可以帮助我吗?
提前致谢。
答案 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相同。 如果它更小,则必须用零填充。