在一个项目上,要用到签名算法,接口是这样写的:
5.1.1. 输入参数为 method= openapi.stockout.create timestamp=2015-04-26 00:00:07 format=xml app_key= testerp_appkey v=2.0 sign_method=md5 customerId =test 5.1.2. 按首字母升序排列 app_key= testerp_appkey customerId = stub-cust-code format=xml method= openapi.stockout.create sign_method=md5 timestamp=2015-04-26 00:00:07 v=2.0 5.1.3. 连接字符串 连接参数名与参数值,并在首尾加上 secret,此处假设 secret=test,如下: testapp_keytesterp_appkeycustomerIdstub-cust-codeformatxmlmethod openapi.stockout.createsign_methodmd5timestamp2015-04-26 00:00:07v2.0 body test 其中: body 用请求中的 body 数据代替 5.1.4. 生成签名 sign 32 位大写 MD5 值-> D06D88CB34B2EC0E5C9BAB396C9542B6 5.1.5. 拼装 URL 请求 将所有参数值转换为 UTF-8 编码,然后拼装,并作 URL ENCODING 如下: http://sandbox.vwms.cn/open/service?method= opeanapi.stockout.create×tamp=2015-04- 26%2000:00:07&format=xml&app_key=testerp_appkey&v=2.0&sign=D06D88CB34B2EC0E5C9B AB396C9542B6&sign_method=md5&customerId=stub-cust-code
做法是这样的:
//timestamp string timestamp = DateTime.Now.ToString(); JObject o = new JObject( new JProperty("app_key", _Setting.Value.app_key.ToString()), new JProperty("customerId", _Setting.Value.customerId.ToString()), new JProperty("format", "xml"), new JProperty("method", "openapi.singleitem.synchronize"), new JProperty("sign_method", "md5"), new JProperty("timestamp", timestamp), new JProperty("v", "2.0") ); //先把上面的进行排序 string s = JsonConvert.SerializeObject(o); Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(s); string Sort_Ret = CommonData.GetSignature(values, ""); //拼接URL链接 string secret = _Setting.Value.secret; string Sign = CommonData.StrToMD5(secret + Sort_Ret + in0 + secret); string url = "" + _Setting.Value.UrlApi.ToString() + "?" + "method=" + "openapi.singleitem.synchronize" + "×tamp=" + timestamp + "" + "&format=xml" + "&app_key=" + _Setting.Value.app_key.ToString() + "" + "&v=2.0" + "&sign=" + Sign + "" + "&sign_method=md5" + "&customerId=" + _Setting.Value.customerId.ToString() + ""; //发送Http 请求 HttpClient client = httpClientFactory.CreateClient(); HttpContent content = new StringContent(in0, Encoding.UTF8, "application/json");//将所有制进行utf-8的编码 var ret = await client.PostAsync(url, content); var rr = await ret.Content.ReadAsStringAsync();
涉及到的方法,一个是排序,一个是得到Sign的值
public static string GetSignature(IDictionary<string, string> parameters, string secret) { // 先将参数以其参数名的字典序升序进行排序 IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters); IEnumerator<KeyValuePair<string, string>> iterator = sortedParams.GetEnumerator(); // 遍历排序后的字典,将所有参数按"keyvaluekeyvalue"格式拼接在一起 StringBuilder basestring = new StringBuilder(); while (iterator.MoveNext()) { string key = iterator.Current.Key; string value = iterator.Current.Value.ToString(); if (!string.IsNullOrEmpty(key) && value != null) { basestring.Append(key).Append(value); } } // 使用MD5对待签名串求签 //string upperCaseStr = StrToMD5(basestring.ToString()); //string result = StrToMD5(upperCaseStr + secret); return basestring.ToString(); } public static string StrToMD5(string str) { byte[] data = Encoding.UTF8.GetBytes(str); MD5 md5 = new MD5CryptoServiceProvider(); byte[] OutBytes = md5.ComputeHash(data); string OutString = ""; for (int i = 0; i < OutBytes.Length; i++) { OutString += OutBytes[i].ToString("x2"); } return OutString.ToUpper(); } public static DateTime GetLocaltime(string StandardTime) { var ChTimeZone = TimeZoneInfo.FindSystemTimeZoneById(StandardTime); DateTime ChTime = TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.Local, ChTimeZone); return ChTime; }