java hash hmac sha1,Python HMAC-SHA1与Java HMAC-SHA1的不同结果

博客探讨了作者在实现HMAC-SHA1算法时遇到的问题,比较了Java和Python代码的输出差异。尽管输入相同,但两个语言得到的哈希值不一致。作者怀疑问题出在Python代码的某个细节上,但尚未找到确切原因。博客提供了详细的Java和Python代码示例,用于生成HMAC-SHA1哈希。
摘要由CSDN通过智能技术生成

我从http://tools.ietf.org/html/rfc6238中借用了HMAC-SHA1 Java代码,并对其进行了一些修改,使其能够在已知输出的情况下使用一个已知的键/消息对。

然后我试图用Python编写相同的代码来验证结果,但是在Python和Java中得到了不同的值。

众所周知,Java值是好的。

Java代码:import java.lang.reflect.UndeclaredThrowableException;

import java.security.GeneralSecurityException;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

import javax.crypto.Mac;

import javax.crypto.spec.SecretKeySpec;

import java.math.BigInteger;

import java.util.TimeZone;

import java.util.Arrays;

public class make_hmac {

private make_hmac() {}

private static byte[] hmac_sha(String crypto, byte[] keyBytes,

byte[] text){

try {

System.out.println("Key is..." + bytesToHex(keyBytes) + "\n");

Mac hmac;

hmac = Mac.getInstance(crypto);

SecretKeySpec macKey =

new SecretKeySpec(keyBytes, "RAW");

hmac.init(macKey);

return hmac.doFinal(text);

} catch (GeneralSecurityException gse) {

throw new UndeclaredThrowableException(gse);

}

}

private static byte[] hexStr2Bytes(String hex){

// Adding one byte to get the right conversion

// Values starting with "0" can be converted

byte[] bArray = new BigInteger("10" + hex,16).toByteArray();

// Copy all the REAL bytes, not the "first"

byte[] ret = new byte[bArray.length - 1];

for (int i = 0; i < ret.length; i++)

ret[i] = bArray[i+1];

return ret;

}

private static final int[] DIGITS_POWER

// 0 1 2 3 4 5 6 7 8

= {1,10,100,1000,10000,100000,1000000,10000000,100000000 };

public static String generateTOTP(String key,

String time,

String returnDigits,

String crypto){

int codeDigits = Integer.decode(returnDigits).intValue();

String result = null;

// Using the counter

// First 8 bytes are for the movingFactor

// Compliant with base RFC 4226 (HOTP)

while (time.length() < 16 )

time = "0" + time;

// Get the HEX in a Byte[]

byte[] msg = hexStr2Bytes(time);

byte[] k = hexStr2Bytes(key);

byte[] hash = hmac_sha(crypto, k, msg);

System.out.println("I hashed key " + bytesToHex(k) + " against message " + bytesToHex(msg) + " and got...\n");

System.out.println("HASHED: " + bytesToHex(hash) + "\n");

// put selected bytes into result int

int offset = hash[hash.length - 1] & 0xf;

int binary =

((hash[offset] & 0x7f) << 24) |

((hash[offset + 1] & 0xff) << 16) |

((hash[offset + 2] & 0xff) << 8) |

(hash[offset + 3] & 0xff);

int otp = binary % DIGITS_POWER[codeDigits];

result = Integer.toString(otp);

while (result.length() < codeDigits) {

result = "0" + result;

}

return result;

}

public static String bytesToHex(byte[] bytes) {

final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

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);

}

public static void main(String[] args) {

// Seed for HMAC-SHA1 - 20 bytes

String seed = "3132333435363738393031323334353637383930";

long T0 = 0;

long X = 30;

long testTime = 1111111109L;

String steps = "0";

long T = (testTime - T0)/X;

steps = Long.toHexString(T).toUpperCase();

while (steps.length() < 16) steps = "0" + steps;

System.out.println(generateTOTP(seed, steps, "8",

"HmacSHA1"));

}

}

Python代码:import hmac

from hashlib import sha1

k = "3132333435363738393031323334353637383930"

msg = "00000000023523EC"

print "I hashed key", k, "against msg", msg, "and got...\n"

a = hmac.new(k, msg, sha1)

print a.digest().encode('hex')

运行Java的结果:Key is...3132333435363738393031323334353637383930

I hashed key 3132333435363738393031323334353637383930 against message 00000000023523EC and got...

HASHED: 278C02E53610F84C40BD9135ACD4101012410A14

07081804

运行Python的结果:I hashed key 3132333435363738393031323334353637383930 against msg 00000000023523EC and got...

fa9362e87c80a1ac61f705b5f9d5095adaec9525

“key”和“message”是相同的,但是Java版本得到的HMAC与Python实现不同。

我怀疑Python代码中的某个地方有一个微妙的错误(因为Java版本与RFC的预期结果相匹配),但是我不确定在哪里。看起来很简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值