一个Java Hmacsha1 签名的C#实现

       前段时间做一个项目,涉及到与一个第三方平台对接。对方平台是java开发的,没有提供C#的sdk,由于涉及到签名问题,所有不得不翻看他们的java sdk,并按照他们的算法翻译成C#。有些问题百度半天也没找到答案,最后好不容易搞定了,特此记录下。

public static String makeSig(TreeMap param,String key){
		try{
			String str = OAuthUtil.sigParam(param);
			String mac =  new BigInteger(Coder.encryptHMAC((str).getBytes("utf-8"), key)).toString();
		    System.out.println("InterfaceService >> MAC :"+mac);
		    return mac;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
private static String sigParam(TreeMap param){
		String str = "";
		//1 排序 2组串
		Set set = param.keySet();
		Iterator it = set.iterator();
		while(it.hasNext()){
			String key = (String)it.next();
			str+=key+"="+param.get(key);
		}
		return str;
	}
/** 
	     * HMAC加密 
	     *  
	     * @param data 
	     * @param key 
	     * @return 
	     * @throws Exception 
	     */  
	    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {  
	  
	        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);  
	        Mac mac = Mac.getInstance(secretKey.getAlgorithm());  
	        mac.init(secretKey);  
	  
	        return mac.doFinal(data);  
	  
	    }  
/** 
     * BASE64解密 
     *  
     * @param key 
     * @return 
     * @throws Exception 
     */  
    public static byte[] decryptBASE64(String key) throws Exception {  
        return (new BASE64Decoder()).decodeBuffer(key);  
    }  

Java相关的代码基本就是这些了,然后用C#进行翻译。

public static string ComputeSign(SortedDictionary parameters,string key)
        {
            if (parameters.Count == 0)
            {
                return string.Empty;
            }

            var list = parameters.Select(r => $"{r.Key}={r.Value}").ToList();
            var toSignString = string.Join("", list.Select(r => r));
            var keyBy = Convert.FromBase64String(key);
            var hmac = new HMACSHA1(keyBy);
            hmac.Initialize();
            hmac.ComputeHash(Encoding.UTF8.GetBytes(toSignString));
            var bigInteger = new BigInteger(hmac.Hash.Reverse().ToArray());

            return bigInteger.ToString();
        }

其中 C#中的 BigInteger 位于 System.Numerics 下,需要添加引用 

最后,进行测试 

Java:

public static void main(String[] args) {
        try {
            TreeMap dic = new TreeMap();
            dic.put("client_id", "826");
            dic.put("grant_type", "authorization_code");
            dic.put("code", "abcd123ef");
            dic.put("state", "ktsvdafz");

            String sig = makeSig(dic, "b6b3c0699dd0920f263eade3df2aad11");
            System.out.println("Sig: " + sig);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

结果:Sig: -76040878703683626175778032011774713322908319476

C#:

var paras = new SortedDictionary
            {
                {"client_id", "826"},
                {"grant_type", "authorization_code"},
                {"code", "abcd123ef"},
                {"state", "ktsvdafz"}
            };

            var sig = OpenAuthBaseEx.ComputeSign(paras, "b6b3c0699dd0920f263eade3df2aad11");

            Console.WriteLine(sig);

结果:Sig: -76040878703683626175778032011774713322908319476

结果也是惊人的一致,完美收官!

 

你可能感兴趣的:(编程语言)