API 传输数据加密

//添加自定义消息处理
config.MessageHandlers.Add(new EncryptMessageHandler());

 

API

    public class EncryptMessageHandler : MessageProcessingHandler
    {
        log4net.ILog logger = log4net.LogManager.GetLogger("EncryptionLogger");

        
        protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {

            if (request.Content.IsMimeMultipartContent())
            {
                return request;
            }
            string[] timeStampStrings = HttpContext.Current.Request.Headers.GetValues("timeStamp");
            string[] accessKeyStrings = HttpContext.Current.Request.Headers.GetValues("accessKey");
            string[] isEncrypt = HttpContext.Current.Request.Headers.GetValues("isEncrypt");
            if (isEncrypt == null||isEncrypt.Length==0 || string.IsNullOrWhiteSpace(isEncrypt[0]) || isEncrypt[0] == 0.ToString())
            {
                if (!(request.RequestUri.PathAndQuery + "").ToLower().Contains("api/file") 
                    && !(request.RequestUri.PathAndQuery + "").ToLower().Contains("api/phone")
                    && !(request.RequestUri.PathAndQuery + "").ToLower().Contains("api/android/displaydata")
                    && !(request.RequestUri.PathAndQuery + "").ToLower().Contains("api/login/getminversion"))
                { 
                    logger.Debug(string.Format("未加密请求:{0},请求IP:{1}",request.RequestUri.PathAndQuery,GetIP()));
                }
                return request;
            }
            if (timeStampStrings == null || timeStampStrings.Length < 1)
            {
                throw new UnauthorizedAccessException("请求的资源没有权限,请先登录或联系管理员");
            }
            if (accessKeyStrings == null || accessKeyStrings.Length < 1)
            {
                throw new UnauthorizedAccessException("请求的资源没有权限,请先登录或联系管理员");
            }
            string accessKey = Encryption.MD5Encrypt(Encryption.key + timeStampStrings[0]);
          
            //判断密钥是否正确
            string key = accessKeyStrings.FirstOrDefault(item => item == accessKey);
            if (!string.IsNullOrEmpty(key))
            {
                // 读取请求body中的数据
                string baseContent = request.Content.ReadAsStringAsync().Result;
     
                // 获取加密的信息
                // 兼容 body: 加密数据  和 body: code=加密数据
                baseContent = baseContent.Match("(code=)*(?<code>[\\S]+)", 2);
             
                // 用加密对象解密数据
                baseContent = Encryption.Decrypt3DES(baseContent, key);

                string baseQuery = string.Empty;
                if (!string.IsNullOrEmpty(request.RequestUri.Query))
                {
                    // 读取请求 url query数据
                    baseQuery = request.RequestUri.Query.Substring(1);
                    baseQuery = baseQuery.Match("(code=)*(?<code>[\\S]+)", 2);
                    baseQuery = Encryption.Decrypt3DES(baseQuery, key);
                }

                // 将解密后的 URL 重置URL请求
                request.RequestUri = new Uri(request.RequestUri.AbsoluteUri.Split('?')[0] + "?" + baseQuery);
                // 将解密后的BODY数据 重置
                var result = JsonConvert.DeserializeObject(baseContent);
                request.Content = new ObjectContent(typeof (object), result, new JsonMediaTypeFormatter());
                return request;
            }
            throw new UnauthorizedAccessException("请求的资源没有权限,请先登录或联系管理员");
        }


        /// <summary>
        /// 获取客户端IP地址
        /// </summary>
        /// <returns></returns>
        public static string GetIP()
        {
            string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.UserHostAddress;
            }
            if (string.IsNullOrEmpty(result))
            {
                return "0.0.0.0";
            }
            return result;
        }

        protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, System.Threading.CancellationToken cancellationToken)
        {
            try
            { 

                //是否加密
                string[] isEncrypt = HttpContext.Current.Request.Headers.GetValues("isEncrypt");
                if (isEncrypt == null || isEncrypt.Length == 0 || string.IsNullOrWhiteSpace(isEncrypt[0]) || isEncrypt[0] == 0.ToString())
                {
                    return response;
                }
                //密钥
                string[] accessKeyStrings = HttpContext.Current.Request.Headers.GetValues("accessKey");
                if (accessKeyStrings == null || accessKeyStrings.Length < 1)
                {
                    throw new UnauthorizedAccessException("请求的资源没有权限,请先登录或联系管理员");
                }
                string result = null;
                if (response.Content != null)
                {
                    result = response.Content.ReadAsStringAsync().Result;
                    string encodeResult = Encryption.Encrypt3DES(result, accessKeyStrings.First());
                    response.Content = new StringContent(encodeResult);
                }

                return response;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

      
      
    }
View Code

 

MD5

        #region MD5加密
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str">欲加密的明文</param>
        /// <returns>加密后的密文</returns>
        public static string MD5Encrypt(string str,string encodeName=null)
        {
            string ret = string.Empty;

            System.Security.Cryptography.MD5 md5 = new MD5CryptoServiceProvider();

            Encoding encode = System.Text.Encoding.Default;
            if (!string.IsNullOrWhiteSpace(encodeName))
            {
                try {
                    var en = Encoding.GetEncoding(encodeName);
                    if (en != null) encode = en;
                }catch{}
                
            }

            byte[] data = encode.GetBytes(str);
            byte[] result = md5.ComputeHash(data);

            for (int i = 0; i < result.Length; i++)
            {
                ret += result[i].ToString("x").PadLeft(2, '0');
            }

            return ret;
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string md5EncryptByUTF8(string str)
        {
            return Encryption.MD5Encrypt(str, "utf-8");
        }


        #endregion
View Code

 

HttpClient辅助类

        /// <summary>
        /// 返回一个设置了基本参数的HttpClient
        /// </summary>
        /// <returns></returns>
        public static HttpClient GetHttpClient()
        {
            var handler = new HttpClientHandler() { }; //UseProxy = true, Proxy = WebRequest.DefaultWebProxy
            if (!string.IsNullOrEmpty(ClientPublicData.LoginToken))
            {
                //把验证需要的token放到cookie中
                handler.CookieContainer = new CookieContainer();
                handler.CookieContainer.Add(new Uri(WebApiClientConfiguration.MyWebApiBaseAddress), new Cookie(WebApiClientConfiguration.TokenCookieName, ClientPublicData.LoginToken));
            }

            //HttpClient httpClient = HttpClientFactory.Create(handler, new LogHandler());
            HttpClient httpClient = HttpClientFactory.Create(handler);
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            //httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
            //httpClient.DefaultRequestHeaders.Add("X-UserAgent", "CSClient");

            httpClient.BaseAddress = new Uri(WebApiClientConfiguration.MyWebApiBaseAddress);
            //httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", AuthorizationValue); //Basic验证方式
            //httpClient.Timeout = new TimeSpan(0, 5, 0);//5分钟超时
            return httpClient;
        }

        /// <summary>
        /// 根据Http状态代码抛出异常
        /// </summary>
        /// <param name="statusCode"></param>
        public static void ThrowException(HttpStatusCode statusCode)
        {
            switch (statusCode)
            {
                case HttpStatusCode.OK:
                    return;//正常代码
                case HttpStatusCode.Unauthorized:
                    throw new UnauthorizedAccessException("请求的资源没有权限,请先登录或联系管理员");
                case HttpStatusCode.NotFound:
                    throw new Exception("请求的资源不在服务器上[404]");
                case HttpStatusCode.RequestTimeout:
                    throw new Exception("请求超时[408]");
                case HttpStatusCode.InternalServerError:
                    throw new Exception("服务器上发生了一般错误[500]");

                default:
                    throw new Exception("请求时发生错误:" + statusCode.ToString() + "[" + (int)statusCode + "]");
            }
        }

        #region 异步方法

        /// <summary>
        /// 封装对服务器url的Post请求
        /// </summary>
        /// <typeparam name="TResult">返回的结果</typeparam>
        /// <param name="url">请求的url地址</param>
        /// <param name="value">请求时传给服务器的参数</param>
        /// <param name="beforeAction">请求前要执行的代码,可为null</param>
        /// <param name="afterAction">请求后要执行的代码,可为null</param>
        /// <param name="isEncrypt">是否加密(1:代表加密,0代表不加密)</param>
        /// <returns></returns>
        public static async Task<TResult> PostAsJsonAsync<TResult>(string url, object value, Action beforeAction = null, Action afterAction = null, int isEncrypt=1)
        {
            url = url.TrimStart('/');
            if (beforeAction != null) beforeAction();
            try
            {
                using (var client = ApiClientHelper.GetHttpClient())
                {

                    client.DefaultRequestHeaders.Add("isEncrypt",isEncrypt.ToString());
                    //时间戳加密
                     string timeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:s");
                     string accessKey = Encryption.MD5Encrypt(Encryption.key + timeStamp);
                     client.DefaultRequestHeaders.Add("timeStamp", timeStamp);
                     client.DefaultRequestHeaders.Add("accessKey", accessKey);
                    
                    string constparam = null;
                    if (isEncrypt==1)
                    {
                        //发送之前数据加密
                        if (value != null)
                        {
                            string param = JsonConvert.SerializeObject(value);
                            constparam = Encryption.Encrypt3DES(param, accessKey);
                        }
                        string baseQuery = string.Empty;
                        int index = url.IndexOf("?", System.StringComparison.Ordinal);
                        if (index != -1)
                        {
                            baseQuery = url.Substring(index + 1);
                            string starturl = url.Substring(0, index + 1);
                            if (!string.IsNullOrEmpty(baseQuery))
                            {
                                baseQuery = Encryption.Encrypt3DES(baseQuery, accessKey);
                                url = starturl + baseQuery;
                            }
                        }
                    }
                    Task<HttpResponseMessage> aTask = client.PostAsJsonAsync<object>(url,isEncrypt==1?constparam:value);
                    HttpResponseMessage response = await aTask;
                    if (response.IsSuccessStatusCode)
                    {
                       string result1 = await response.Content.ReadAsStringAsync();
                        //解密
                        if (isEncrypt == 1)
                        {
                            result1 = Encryption.Decrypt3DES(result1, accessKey);
                        }
                        var result = JsonConvert.DeserializeObject<TResult>(result1);
                       return result;
                    }
                    //response.EnsureSuccessStatusCode();
                    ThrowException(response.StatusCode);
                    throw new Exception("请求时发生错误");
                }
            }
            finally
            {
                if (afterAction != null) afterAction();
            }
        }

        /// <summary>
        /// 封装对服务器url的Get请求
        /// </summary>
        /// <typeparam name="TResult">返回的结果</typeparam>
        /// <param name="url">请求的url地址</param>
        /// <param name="beforeAction">请求前要执行的代码,可为null</param>
        /// <param name="afterAction">请求后要执行的代码,可为null</param>
        /// <param name="isEncrypt">是否加密(1:代表加密,0代表不加密)</param>
        /// <returns></returns>
        public static async Task<TResult> GetAsJsonAsync<TResult>(string url, Action beforeAction = null, Action afterAction = null,int isEncrypt=1)
        {
            url = url.TrimStart('/');
          
            if (beforeAction != null) beforeAction();
            try
            {
                using (var client = ApiClientHelper.GetHttpClient())
                {
                   client.DefaultRequestHeaders.Add("isEncrypt", isEncrypt.ToString());
                   //时间戳加密
                   string timeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:s");
                   string accessKey = Encryption.MD5Encrypt(Encryption.key + timeStamp);
                   client.DefaultRequestHeaders.Add("timeStamp", timeStamp);
                   client.DefaultRequestHeaders.Add("accessKey", accessKey);
                    if (isEncrypt == 1)
                    {
                        //处理数据加密
                        string baseQuery = string.Empty;
                        int index = url.IndexOf("?", System.StringComparison.Ordinal);
                        if (index != -1)
                        {
                            baseQuery = url.Substring(index + 1);
                            string starturl = url.Substring(0, index + 1);
                            if (!string.IsNullOrEmpty(baseQuery))
                            {
                                baseQuery = Encryption.Encrypt3DES(baseQuery, accessKey);
                                url = starturl + baseQuery;
                            }
                        }
                    }
                    string result1 = await  client.GetStringAsync(url);
                    //处理数据解密
                    if (isEncrypt == 1)
                    {
                        result1 = Encryption.Decrypt3DES(result1, accessKey);
                    }
                    return JsonConvert.DeserializeObject<TResult>(result1);
                }
            }
           
            finally
            {
                if (afterAction != null) afterAction();
            }
        }

        #endregion

        #region 同步方法

        ///// <summary>
        ///// 封装对服务器url的Post请求
        ///// </summary>
        ///// <typeparam name="TResult">返回的结果</typeparam>
        ///// <param name="url">请求的url地址</param>
        ///// <param name="value">请求时传给服务器的参数</param>
        ///// <returns></returns>
        //public static TResult PostAsJson<TResult>(string url, object value)
        //{
        //    url = url.TrimStart('/');
        //    using (var client = ApiClientHelper.GetHttpClient())
        //    {
        //        HttpResponseMessage response = client.PostAsJsonAsync<object>(url, value).Result;
        //        if (response.IsSuccessStatusCode)
        //        {
        //            TResult result = response.Content.ReadAsAsync<TResult>().Result;
        //            return result;
        //        }
        //        //response.EnsureSuccessStatusCode();
        //        ThrowException(response.StatusCode);
        //        throw new Exception("请求时发生错误");
        //    }
        //}

        /// <summary>
        /// 封装对服务器url的Get请求
        /// </summary>
        /// <typeparam name="TResult">返回的结果</typeparam>
        /// <param name="url">请求的url地址</param>
        /// <returns></returns>
        public static TResult GetAsJson<TResult>(string url)
        {
            url = url.TrimStart('/');
            using (var client = ApiClientHelper.GetHttpClient())
            {
                string response = client.GetStringAsync(url).Result;
                return JsonConvert.DeserializeObject<TResult>(response);
            }
        }

        #endregion

        #region 上传下载文件
        public static async Task<IList<VMCustLoanDocInfo>> UploadFile(List<VMCustLoanDocInfo> infos, List<FileStream> fileStreams)
        {
            List<VMCustLoanDocInfo> result = new List<VMCustLoanDocInfo>();
            string url = "File/UploadByte";
            Random random = new Random(int.Parse(DateTime.Now.ToString("HHmmss")));
            int packSize = 30 + random.Next(10);
            int dataMaxLenth = packSize * 1024;
            for (int i = 0; i < infos.Count; i++)
            {
                DateTime nowFrom = DateTime.Now;
                var fileStream = fileStreams[i];
                var info = infos[i];
                string tmpGuid = Utility.Util.GetGuid();

                byte[] bytes = new byte[dataMaxLenth];
                int numBytesToRead = dataMaxLenth;
                int numBytesRead = 0;
                while (numBytesToRead > 0)
                {
                    fileStream.Seek(numBytesRead, SeekOrigin.Begin);
                    // Read may return anything from 0 to numBytesToRead.
                    int n = 0;
                    try
                    {
                        n = fileStream.Read(bytes, 0, numBytesToRead);
                    }
                    catch (Exception ee)
                    {
                        throw ee;
                    }

                    // Break when the end of the file is reached.
                    if (n == 0)
                        break;

                    VMUploadData vmUpload = new VMUploadData() { TempGuid = tmpGuid, Seek = numBytesRead };
                    byte[] data = new byte[n];
                    Array.Copy(bytes, 0, data, 0, n);
                    vmUpload.Data = data;
                    //提交
                    byte isOK = 0;
                    for (int repeatTimes = 1; repeatTimes <= 10; repeatTimes++)
                    {
                        //Console.WriteLine(repeatTimes);
                        try
                        {
                            isOK = await ApiClientHelper.PostAsJsonAsync<byte>(url, vmUpload,null,null,0);
                        }
                        catch
                        { }
                        if (isOK == 1) break;
                    }
                    if (isOK != 1)
                    {
                        throw new Exception("上传" + info.DocName + "失败,请重试");
                    }

                    numBytesRead += n;
                }//while
                string urlFinish = "File/UploadFinish";
                VMUploadFinish vmFinish = new VMUploadFinish() { TempGuid = tmpGuid, VMDocInfo = info };
                vmFinish.TotalUsedTime = DateTime.Now - nowFrom;
                VMCustLoanDocInfo tmpInfo = null;
                try
                {
                    tmpInfo = await ApiClientHelper.PostAsJsonAsync<VMCustLoanDocInfo>(urlFinish, vmFinish,null,null,0);
                }
                catch
                {
                }

                if (null == tmpInfo)
                    tmpInfo = await ApiClientHelper.PostAsJsonAsync<VMCustLoanDocInfo>(urlFinish, vmFinish,null,null,0); //重试

                if (null == tmpInfo)
                {
                    throw new Exception("上传" + info.DocName + "失败,请重试");
                }
                result.Add(tmpInfo);
            }//for
            return result;
        }
View Code

 

posted @ 2018-08-07 15:34  bxzjzg  阅读(759)  评论(0编辑  收藏  举报