0

我正在尝试使用消息和密钥使我的 Java 程序生成签名。我的 C# 程序应该使用相同的消息和密钥生成相同的令牌。

但是,有些东西不能正常工作,因为生成的令牌不同。

有人可以找出这两个程序之间的区别以及为什么它们不生成匹配的密钥吗?

Java 代码:

this.algorithm = "hmacSHA256";
private static Mac mac;
String message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id urn";
String secretKey = "5771CC06-B86D-41A6-AB39-9CA2BA338E27";

if( mac == null ) {
    mac = Mac.getInstance(algorithm);
    SecretKeySpec secret = new SecretKeySpec(secretKey.getBytes("US-ASCII"), 
        mac.getAlgorithm());
    mac.init(secret);
}
this.signature = new String(Base64.encodeBase64(mac.doFinal(message.getBytes("US-ASCII"))));

C#代码:

string message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id urn";
string secret = "5771CC06-B86D-41A6-AB39-9CA2BA338E27";

secret = secret ?? "";
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new System.Security.Cryptography.HMACSHA256(keyByte))
{
    byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
    return Convert.ToBase64String(hashmessage);
}
4

2 回答 2

2

我可以看到您在 C# 中使用 HMACSHA256 哈希算法。但是你在 Java 中使用什么算法?

于 2013-09-26T15:35:02.897 回答
1

您的问题与加密无关。我稍微更改了代码,使其在主函数中独立运行,并且都返回相同的结果:

rO7Ly1WIR+d4AGXaDvIOYH3vVm2NvyFwbr3E3rQaw4I=

我的Java代码是:

package com.test.so;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class MessageHashTest {

    public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        String algorithm = "hmacSHA256";
        String message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id urn";
        String secretKey = "5771CC06-B86D-41A6-AB39-9CA2BA338E27";

        Mac mac = Mac.getInstance(algorithm);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getBytes("US-ASCII"), 
        mac.getAlgorithm());
        mac.init(secret);
        String signature = new String(Base64.encodeBase64(mac.doFinal(message.getBytes("US-ASCII"))));
        System.out.println(signature);
    }
}

我的 .NET 代码是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace MessageHashTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id urn";
            string secret = "5771CC06-B86D-41A6-AB39-9CA2BA338E27";

            var encoding = new System.Text.ASCIIEncoding();
            byte[] keyByte = encoding.GetBytes(secret);
            byte[] messageBytes = encoding.GetBytes(message);
            using (var hmacsha256 = new HMACSHA256(keyByte))
            {
                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
                Console.WriteLine(Convert.ToBase64String(hashmessage));
            }
        }
    }
}

您的代码中可能存在的问题是:

  • Java中MAC实例的重用。我不知道你是否可以多次使用。它可能不再为新消息正确初始化。
  • secret = secret ?? "": 为什么需要这个?你是不是在什么地方泄露了这个秘密?您是否使用错误的秘密创建哈希?
于 2013-09-26T15:58:15.770 回答