java - Java 中的 HMAC-SHA256/从 C# 翻译

标签 java c# .net eclipse encryption

我有这段 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...

如有任何帮助,我们将不胜感激!

最佳答案

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

Java 始终使用有符号值,因此 Integer.toHexString(num); 返回许多负 32 位数字(您可以在输出。

因此,如果将字节转换为(无符号)int,则始终必须添加 & 0xFF:

Integer.toHexString(0xff & num);

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

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

关于java - Java 中的 HMAC-SHA256/从 C# 翻译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39354009/

相关文章:

java - Hadoop 如何获取没有存储在 HDFS 上的输入数据?

c# - 使用 C# 将多个音频样本混合到单个文件中

.NET和Lotus Notes互操作

java - 从 HIVE UDF 读取 HDFS 文件 - 执行错误,返回代码 101 FunctionTask。无法初始化类

java - 如何构建在 java 中动态调整大小的布局?

java - mule 中的对象存储异常

c# - 在 C# 中将 12 小时格式转换为 24 小时格式

c# - 在 C# 中链接 IEnumerables?

.net - 授予对 Outlook 应用程序的访问权限

c# - 使用 RX 查询,如何在每秒 3 秒的窗口内获取哪些记录具有相同状态?