首页 新闻 会员 周边 捐助

紧急求助 http://mta.qq.com/h5/api/ctr_user_realtime 接口访问失败

0
悬赏园豆:100 [已解决问题] 解决于 2017-07-24 17:30

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。

哪啊哪啊神去村的主页 哪啊哪啊神去村 | 初学一级 | 园豆:96
提问于:2017-07-24 15:26
< >
分享
最佳答案
1
public object GetUserRealtimeSign()
{
     ///....忽略
     string md5value = MD5Encrypt32(“你的私钥”+sringkv);
     return md5value;
}
收获园豆:100
Timetombs | 老鸟四级 |园豆:3959 | 2017-07-24 17:25

我也刚刚找到问题,已经解决了,非常感谢!

哪啊哪啊神去村 | 园豆:96 (初学一级) | 2017-07-24 17:26
其他回答(2)
0

应该是你的MD5加密的问题


        public static string MD5Encrypt32(string password)
        {
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
string md5 = BitConverter.ToString(hashmd5.ComputeHash(Encoding.UTF8.GetBytes(str))).Replace("-", "");

return md5;

}

换成这个

刘宏玺 | 园豆:14020 (专家六级) | 2017-07-24 16:32

这个我用过后也有问题,不过还是谢谢你。

这个我粘贴出来方便用到的朋友:

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();
}

支持(0) 反对(0) 哪啊哪啊神去村 | 园豆:96 (初学一级) | 2017-07-24 17:28
-1

请问解决方案是什么呀。 没看懂

winteri | 园豆:202 (菜鸟二级) | 2017-11-13 13:28
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册