码迷,mamicode.com
首页 > 移动开发 > 详细

WebApi与手机客户端通信安全机制

时间:2015-10-22 01:28:27      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:

WebApi与手机客户端通信安全机制

最近公司有几个项目需要开发手机客户端,服务器端选用WebApi,那么如何保证手机客户端在请求服务器端时数据不被篡改,如何保证一个http请求的失效机制,下面总结一下我们在项目中针对这两个问题的解决方案。

基本思路如下:

  用户在成功登陆app客户端之后,手机客户端向服务器端发出的所有的http请求在请求头(HttpHeader)上都会带上下面三个参数:1、Uid(用户ID),2、Ts(时间戳),3、Sign(签名)。其中Ts是当前时间减去1970-1-1得到的10位的时间时间戳数字,Sign是接口中所有http请求参数与Uid、Ts经过MD5加密后得到的一个字符串。

具体实现如下(客户端的实现,手机客户端生成下面两个参数的思路是一样的):

1、Ts时间戳

Ts参数可以保证请求的时效性,在手机客户端生成的Ts,在服务器端验证一下,保证请求是在我们规定的时间段内,具体代码如下:

(1)、生成Ts(C#)代码如下,Andriod和IOS可以同理生成

技术分享
 /// <summary>
        /// 获取十位的时间戳
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public string GenerateTimeStamp(DateTime dt)
        {
            // Default implementation of UNIX time of the current UTC time  
            TimeSpan ts = dt.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }  
技术分享

(2)、服务器端端验证Ts代码如下,我们规定从手机客户端发到服务器端的请求有效期为5分钟,时间戳参数是跟在Http请求头中

技术分享
//获取请求头信息
            var requestHeader = HttpContext.Current.Request.Headers;
           
            //10位时间戳
            var Ts = requestHeader.Get("Ts");
            //验证Ts是否合法(请求时间有效时间为:加减5分钟)
            var ts = Ts;//10位时间戳
            if (ts.Length != 10)
            {
                var resp = Request.CreateResponse<string>(HttpStatusCode.OK, "请求已过期", "application/json"); ;

                throw new HttpResponseException(resp);
            }
            var tsDate = ComHelper.ConvertIntDateTime(ts.ToString());
            if (tsDate > DateTime.Now.AddMinutes(5) || tsDate < DateTime.Now.AddMinutes(-5))
            {
                var resp = Request.CreateResponse<string>(HttpStatusCode.OK, "请求已过期", "application/json"); ;

                throw new HttpResponseException(resp);
            }
技术分享

(3)、ComHelper公共类代码如下

技术分享 ComHelper

 

2、Sign签名

(1)、sign的生成规则:服务器端接口中的所有参数+Uid+Ts,去除掉参数中值为空的参数后, 按照参数key值排序,用&链接,并全部转化为小写,然后用MD5加密,通过HttpHeader发送到服务器端接口。

生成Sign大代码如下(C#),Android和IOS可以同理生成

假如手机客户端请求的一个API接口为:http://weapi.com/order/getlist?StatusID=1&CarID=2&CityID=3&name=&key=222

sign=md5(carid=2&cityid=3&key=222&statusid=1&ts=0123456789&uid=110)

(2)、验证客户端的Sign,防止参数被修改

技术分享
 //请求签名,客户端生成的签名
            var Sign = requestHeader.Get("Sign");
//排序字典,按照key排序
            SortedDictionary<string, string> postValue = null;
            //获取请求中所有的参数
            postValue = ComHelper.GetRequestSortDic(true);
            postValue.Add("Uid", Uid);//API账户名称
            postValue.Add("Ts", Ts);//10位时间戳 

            string APIPrivateKey = "2D7E7C96-DAC5-4526-96C3-C60CDEC4B120";//客户端和手机端保持一致
            //服务器端生成的Sign
            string mysign = ComHelper.GetResponseMysign(postValue, APIPrivateKey);
            if (!Sign.Equals(mysign, StringComparison.InvariantCultureIgnoreCase))
            {
                var resp = Request.CreateResponse<string>(HttpStatusCode.OK, "签名错误", "application/json"); ;

                throw new HttpResponseException(resp);
            }
技术分享

 3、模拟测试

 (1)C#模拟Http请求,代码如下

技术分享
 //请求的API地址
            string url = "http://localhost:51942/api/Values/Get?StatusID=1&CarID=2&CityID=3&name=&key=1233";
            //生成Ts
            string Ts = ComHelper.GenerateTimeStamp(DateTime.Now);
            //SortedDictionary会自动按照key值排序
            SortedDictionary<string, string> sortDic = new SortedDictionary<string, string>();
            sortDic.Add("StatusID", "1");
            sortDic.Add("CarID", "2");
            sortDic.Add("CityID", "3");
            sortDic.Add("name", "");
            sortDic.Add("key", "1233");
            sortDic.Add("Uid","110");
            sortDic.Add("Ts", Ts);
            string APIPrivateKey = "2D7E7C96-DAC5-4526-96C3-C60CDEC4B120";//客户端和手机端保持一致,md5加密多使用了一个参数
            //获取Sign签名
            string Sign = ComHelper.GetResponseMysign(sortDic, APIPrivateKey);
            
            //发送请求
            System.Net.WebRequest wReq = System.Net.WebRequest.Create(url);
            wReq.Headers.Add("Uid", "110");
            wReq.Headers.Add("Ts", Ts);
            wReq.Headers.Add("Sign", Sign);

            System.Net.WebResponse wResp = wReq.GetResponse();
            System.IO.Stream respStream = wResp.GetResponseStream();

            using (System.IO.StreamReader reader = new System.IO.StreamReader(respStream, Encoding.UTF8))
            {
                string res= reader.ReadToEnd();
            }
技术分享

 

(2)服务器端验证参数,参数验证写在BaseApiController.cs文件中,只要继承该类的都可以验证客户端传过来的参数

技术分享
 public class ValuesController : BaseApiController
    {
        
        // GET api/values
        public IEnumerable<string> Get(string StatusID,string CarID,string CityID,string name, string key)
        {
            return new string[] { "value1", "value2" };
        }
技术分享

 

技术分享 BaseApiController

 大家可以加我的QQ:530439142,一起交流成长

WebApi与手机客户端通信安全机制 Eric.Chen 2015-10-20 18:23 阅读:758 评论:7  
 
WebApi 服务监控 Eric.Chen 2015-01-22 11:28 阅读:1553 评论:2  
 
webAPI 自动生成帮助文档 Eric.Chen 2014-08-22 10:50 阅读:1256 评论:4  
 
MVC4+WebApi+Redis Session共享练习(下) Eric.Chen 2013-08-09 21:49 阅读:2156 评论:1  
 
MVC4+WebApi+Redis Session共享练习(上) Eric.Chen 2013-08-08 20:41 阅读:3992 评论:12  

WebApi与手机客户端通信安全机制

标签:

原文地址:http://www.cnblogs.com/Leo_wl/p/4899652.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!