C#重写VIVO支付SDK VivoSignUtils

最近公司游戏要接Vivo,公司的服务器是.net的无奈,把vivo开发文档里的VivoSignUtils改成了C#语言的。分享出来给大家。

public class VivoSignUtils
    {
        // 签名key
        public static String SIGNATURE = "signature";
        // 签名方法key
        public static String SIGN_METHOD = "signmethod";
        // =
        public static String QSTRING_EQUAL = "=";
        // &
        public static String QSTRING_SPLIT = "&";

        /**
	 * 拼接请求字符串
	 * 
	 * @param req
	 *            请求要素
	 * @param key
	 *            vivo分配给商户的密钥
	 * @return 请求字符串
	 */
        public static String buildReq(Dictionary<String, String> req, String key)
        {
            // 除去数组中的空值和签名参数
            Dictionary<String, String> filteredReq = paraFilter(req);
            // 根据参数获取vivo签名
            String signature = getVivoSign(filteredReq, key);
            // 签名结果与签名方式加入请求提交参数组中
            filteredReq.Add(SIGNATURE, signature);
            filteredReq.Add(SIGN_METHOD, "MD5");

            return createLinkString(filteredReq, false, true); // 请求字符串,key不需要排序,value需要URL编码
        }

        /**
	 * 异步通知消息验签
	 * 
	 * @param para
	 *            异步通知消息
	 * @param key
	 *            vivo分配给商户的密钥
	 * @return 验签结果
	 */
        public static bool verifySignature(Dictionary<String, String> para, String key)
        {
            // 除去数组中的空值和签名参数
            Dictionary<String, String> filteredReq = paraFilter(para);
            // 根据参数获取vivo签名
            String signature = getVivoSign(filteredReq, key);
            // 获取参数中的签名值
            String respSignature = para[SIGNATURE];
            //System.out.println("服务器签名:" + signature + " | 请求消息中的签名:" + respSignature);
            // 对比签名值
            if (null != respSignature && respSignature.Equals(signature))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /**
	 * 获取vivo签名
	 * 
	 * @param para
	 *            参与签名的要素<key,value>
	 * @param key
	 *            vivo分配给商户的密钥
	 * @return 签名结果
	 */
        public static String getVivoSign(Dictionary<String, String> para, String key)
        {
            // 除去数组中的空值和签名参数
            Dictionary<String, String> filteredReq = paraFilter(para);

            String prestr = createLinkString(filteredReq, true, false); // 得到待签名字符串
            // 需要对map进行sort,不需要对value进行URL编码
            prestr = prestr + QSTRING_SPLIT + md5Summary(key);

            return md5Summary(prestr);
        }
        /**
	 * 除去请求要素中的空值和签名参数
	 * 
	 * @param para
	 *            请求要素
	 * @return 去掉空值与签名参数后的请求要素
	 */
        public static Dictionary<String, String> paraFilter(Dictionary<String, String> para)
        {

            Dictionary<String, String> result = new Dictionary<String, String>();

            if (para == null || para.Count <= 0)
            {
                return result;
            }
            foreach (string key in para.Keys)
            {
                string value = para[key];
                if (value == null || value.Equals(string.Empty) || key.ToLower().Equals(SIGNATURE) || key.ToLower().Equals(SIGN_METHOD))
                {
                    continue;
                }
                result.Add(key, value);
            }
            return result;
        }

        /**
	 * 把请求要素按照“参数=参数值”的模式用“&”字符拼接成字符串
	 * 
	 * @param para
	 *            请求要素
	 * @param sort
	 *            是否需要根据key值作升序排列
	 * @param encode
	 *            是否需要URL编码
	 * @return 拼接成的字符串
	 */
        public static String createLinkString(Dictionary<String, String> para, bool sort, bool encode)
        {

            List<String> keys = new List<String>(para.Keys);

            if (sort)
                keys.Sort();

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < keys.Count; i++)
            {
                String key = keys[i];
                String value = para[key];

                if (encode)
                {
                    try
                    {
                        value = HttpUtility.UrlDecode(value, Encoding.UTF8);
                    }
                    catch (Exception e)
                    {
                    }
                }

                if (i == keys.Count - 1)
                {// 拼接时,不包括最后一个&字符
                    sb.Append(key).Append(QSTRING_EQUAL).Append(value);
                }
                else
                {
                    sb.Append(key).Append(QSTRING_EQUAL).Append(value).Append(QSTRING_SPLIT);
                }
            }
            return sb.ToString();
        }

        /**
	 * 对传入的参数进行MD5摘要
	 * 
	 * @param str
	 *            需进行MD5摘要的数据
	 * @return MD5摘要值
	 */
        public static String md5Summary(String str)
        {
            if (str == null)
            {
                return null;
            }

            StringBuilder md5data = new StringBuilder();
            MD5 md = MD5.Create();
            try
            {
                byte[] bytes = md.ComputeHash(Encoding.UTF8.GetBytes(str));
                foreach (byte b in bytes)
                {
                    md5data.Append(b.ToString("x2"));//先把byte转成2位的16进制数然后追加进去
                }
            }
            catch(Exception e)
            {
                throw e;
            }
            return md5data.ToString();
        }
    }

  嘛嘛 就是把VivoSignUtils直接复制粘贴,然后把java的部分方法改成了C#的方法。 

posted @ 2017-04-19 20:07  脑残之神  阅读(344)  评论(0编辑  收藏  举报