Java中的php pack('H *',$ securesecret)等价物

时间:2016-09-22 09:05:27

标签: java php sha256 pack

在没有包功能的PHP中

$message = "hello world";
$key = "7E066";
echo hash_hmac('SHA256',$message, $key);

我得到0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e

在Java中

String data = "hello world";
String key  = "7E066";
System.out.println(hmacSha(key,data, "HmacSHA256"));

private static String hmacSha(String KEY, String VALUE, String SHA_TYPE) {
        try {

            SecretKeySpec signingKey = new SecretKeySpec(KEY.getBytes("UTF-8"), SHA_TYPE);
            Mac mac = Mac.getInstance(SHA_TYPE);
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(VALUE.getBytes("UTF-8"));

            byte[] hexArray = {
                    (byte)'0', (byte)'1', (byte)'2', (byte)'3',
                    (byte)'4', (byte)'5', (byte)'6', (byte)'7',
                    (byte)'8', (byte)'9', (byte)'a', (byte)'b',
                    (byte)'c', (byte)'d', (byte)'e', (byte)'f'
            };
            byte[] hexChars = new byte[rawHmac.length * 2];
            for ( int j = 0; j < rawHmac.length; j++ ) {
                int v = rawHmac[j] & 0xFF;
                hexChars[j * 2] = hexArray[v >>> 4];
                hexChars[j * 2 + 1] = hexArray[v & 0x0F];
            }
            return new String(hexChars);
        }
        catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

我也得到0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e。

PHP with Pack功能

$message = "hello world";
$key = "7E066";
echo hash_hmac('SHA256',$message, pack('H*',$key));

我得到33e97719c1b98f64bd0394e7fe94f43eae927e15f9eda15aeff0830bc3dd2fc3

我不明白pack函数的作用,我不能在Java中编写相同的函数。有人可以帮我吗?

2 个答案:

答案 0 :(得分:0)

试试这个:

public String pack(String hex) {
    String input = hex.length() % 2 == 0 ? hex : hex  + "0";
    StringBuilder output = new StringBuilder();
    for (int i = 0; i < input.length(); i+=2) {
        String str = input.substring(i, i+2);
        output.append((char)Integer.parseInt(str, 16));
    }
    return output.toString();
}

对于这些数据,它会准确返回您需要的内容:

    String data = "hello world";
    String key  = "7E066";
    System.out.println(hmacSha(key,data, "HmacSHA256"));
    System.out.println(hmacSha(pack(key), data, "HmacSHA256"));

0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e
33e97719c1b98f64bd0394e7fe94f43eae927e15f9eda15aeff0830bc3dd2fc3

诀窍是,用于奇数长度的输入十六进制字符串的pack()PHP函数将其向左移动,即在值的右侧添加一个零。这是因为只能为偶数长度的输入十六进制字符串计算二进制字符串。

答案 1 :(得分:0)

就我而言,只能这样做:

import org.apache.geronimo.mail.util.Hex;

public class TestEncoding {

    public static void main(String[] args) {
        System.out.println(Hex.decode(("48398018")));
    }
}

结果: H9�

那是等效的PHP代码:

$nonce = 48398018;
pack('H*', $nonce);
echo $nonce;

结果:H9�