【问题标题】:HMAC-SHA256 in Java/ Translate from C#Java 中的 HMAC-SHA256/从 C# 翻译
【发布时间】:2017-01-14 04:57:34
【问题描述】:

我在 C# 中有这段代码:

byte[] bytes = Encoding.Default.GetBytes("secret key");
int value = checked((int)Math.Round((currentDateTime - dateTimeOf1970).TotalSeconds));
HMACSHA256 hMACSHA = new HMACSHA256(bytes);
string text2 = this.toHexString(hMACSHA.ComputeHash(Encoding.Default.GetBytes(value.ToString() + "/" + url)));

其中的 toHexString 方法是这样的:

private string toHexString (byte[] bytes)
    {
        string text = "";
        checked
        {
            for (int i = 0; i < bytes.Length; i++)
            {
                byte b = bytes[i];
                int num = (int)b;
                string text2 = num.ToString("X").ToLower();
                if (text2.Length < 2)
                {
                    text2 = "0" + text2;
                }
                text += text2;
            }
            return text;
        }
    }

现在我想在 Java 中使用它,由于我的 Java 技能不如我的 C# 技能,我正在想办法翻译它。我翻译的toHexString方法是这样的:

private static String toHexString (byte[] bytes) {
    String text = "";
    for (int i = 0; i < bytes.length; i++) {
        byte b = bytes[i];
        int num = (int) b;
        String text2 = Integer.toHexString(num);
        if (text2.length() < 2) {
            text2 = "0" + text2;
        }
        text += text2;

    }

    return text;

}

这很好用,产生与 C# 版本相同的输出。

现在到另一种方法(使用 HMCAS-SHA256),我继续翻译它:

//creating the timestamp
    long timestamp = System.currentTimeMillis() / 1000;
    //getting the int value of it
    int value = (int) timestamp;

    //just a string that is the value of the hmac
    String input = String.valueOf(value) + "/" + url;
    //new hmac instance
    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    //my secret key where bytes is "my key".getBytes();
    SecretKeySpec secret_key = new SecretKeySpec(bytes, "HmacSHA256");
    sha256_HMAC.init(secret_key);
    //trying to have as string
    String txt2 = toHexString (sha256_HMAC.doFinal(input.getBytes()));

问题是它不会产生相同的输出,

C#版本(应该如何):

12eb558b98dd9a5429e7676640f3dd4122941a575ffa9dc20318...

Java 版本:

fffffff8fffffff87215ffffffb232ffffffeeffffff9069fffffffc6d4cffffffb667ff...

任何帮助将不胜感激!

【问题讨论】:

  • 您的 C# 版本可以通过去掉整个“如果长度小于 2,添加一个 0”位并将 ToString() 参数从 X 更改为 X2 来改进。另一个改进是使用StringBuilder 来构建text,而不是做一堆串联。
  • 谢谢,我的编程速度很快,但是一旦我弄清楚它在 Java 中是如何工作的,肯定会用你建议的东西来改进它。

标签: java c# .net eclipse encryption


【解决方案1】:

您的主要问题是您的 Java toHexString() 方法搞砸了。

Java 总是使用带符号的值,因此 Integer.toHexString(num); 返回许多负的 32 位数字(您可以在输出中看到 ff

因此,如果您将字节转换为(无符号)整数,您始终必须添加 &amp; 0xFF

Integer.toHexString(0xff & num);

无论如何,许多库中都有字节数组到十六进制字符串的方法。因此没有必要再次编码。我更喜欢 apache commons 编解码器库中的 Hex 类。

顺便说一句:您在 C# 和 Java 中使用默认编码,但即使在同一台机器上,这也不一定意味着编码相同。请改用 UTF-8 之类的固定格式。

【讨论】:

  • 非常感谢,这解决了问题。我还编辑了编码,因此我现在只使用 UTF-8。
猜你喜欢
  • 2020-10-18
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多