MTA HTML5网站统计的腾讯接口访问总是sign失败。{"code":60002,"info":"wrong sign","data":[]}
这里是技术文档:
http://developer.qq.com/wiki/mta/HTML5接入/MTA%20HTML5统计API文档/MTA%20HTML5统计API文档.html
app_id因为牵涉到公司的机密用00000000表示。
这是全部代码实现:
using MtaTest.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace MtaTest.Controllers
{
public class UserRealtimeController : Controller
{
// GET: UserRealtime
public ActionResult Index()
{
return View();
}
public object HttpGetUserRealtime()
{
string sign = GetUserRealtimeSign().ToString();
string url = "http://mta.qq.com/h5/api/ctr_user_realtime?app_id=00000000&page=1&sign=" + sign;
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.Accept = "text/html, application/xhtml+xml, */*";
request.ContentType = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
public object GetUserRealtimeSign()
{
Dictionary<string, string> key = new Dictionary<string, string>();
key.Add("app_id", "00000000");
key.Add("page", "1");
key.OrderBy(c => c.Key);
string sringkv = "";
foreach (var item in key)
{
sringkv += item.Key + "=" + item.Value;
}
string md5value = MD5Encrypt16(sringkv);
return md5value;
}
/// <summary>
/// 16位MD5加密
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public static string MD5Encrypt16(string password)
{
var md5 = new MD5CryptoServiceProvider();
string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(password)), 4, 8);
t2 = t2.Replace("-", "");
return t2;
}
/// <summary>
/// 32位MD5加密
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public static string MD5Encrypt32(string password)
{
string cl = password;
string pwd = "";
MD5 md5 = MD5.Create(); //实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 0; i < s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
pwd = pwd + s[i].ToString("X");
}
return pwd;
}
public static string MD5Encrypt64(string password)
{
string cl = password;
//string pwd = "";
MD5 md5 = MD5.Create(); //实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
return Convert.ToBase64String(s);
}
}
}
主要是sign的生成算法不对,希望做过的朋友帮忙啊。
sig生成算法
双方维护同一份私钥,在发起请求的时候,发起方(合作方)将当前的请求参数数组,按照key值进行排序,然后'key=value'拼接到加密串后,进行md5的编码。接收方(H5轻应用统计)以同样的处理方式,对ts<=30分钟的请求进行处理,sig一致则合法,否则失败。如下为php的对应的sig生成算法举例:
1
2
3
4
5
6
7
|
$secret_key = '3023IU&^_W(5#@' ; ksort($params); foreach ($params as $key => $value) { $secret_key.= $key. '=' .$value; } $sign = md5($secret_key); return $sign; |
$params 为所有请求的参数数组,key为参数名,value为值。
secret_key为注册成功后每个app对应返回的secret_key。
public object GetUserRealtimeSign() { ///....忽略 string md5value = MD5Encrypt32(“你的私钥”+sringkv); return md5value; }
我也刚刚找到问题,已经解决了,非常感谢!
应该是你的MD5加密的问题
public static string MD5Encrypt32(string password)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
string md5 = BitConverter.ToString(hashmd5.ComputeHash(Encoding.UTF8.GetBytes(str))).Replace("-", "");
return md5;
}
换成这个
这个我用过后也有问题,不过还是谢谢你。
这个我粘贴出来方便用到的朋友:
public static string GetMd5String(string source)
{
MD5 mD = MD5.Create();
UTF8Encoding uTF8Encoding = new UTF8Encoding();
byte[] bytes = uTF8Encoding.GetBytes(source);
byte[] array = mD.ComputeHash(bytes);
StringBuilder stringBuilder = new StringBuilder();
byte[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
byte b = array2[i];
stringBuilder.Append(b.ToString("x2"));
}
return stringBuilder.ToString();
}
请问解决方案是什么呀。 没看懂