public static class EncrypExtends { //默认密钥向量 private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; internal static string Key = "*@&$(@#H"; //// <summary> /// DES加密字符串 /// </summary> /// <param>待加密的字符串</param> /// <param>加密密钥,要求为8位</param> /// <returns>加密成功返回加密后的字符串,失败返回源串</returns> public static string EncryptDES(this string encryptString, string encryptKey) { try { byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8)); byte[] rgbIV = Keys; byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length); cStream.FlushFinalBlock(); return Convert.ToBase64String(mStream.ToArray()); } catch { return encryptString; } } //// <summary> /// DES解密字符串 /// </summary> /// <param>待解密的字符串</param> /// <param>解密密钥,要求为8位,和加密密钥相同</param> /// <returns>解密成功返回解密后的字符串,失败返源串</returns> public static string DecryptDES(this string decryptString, string key) { try { byte[] rgbKey = Encoding.UTF8.GetBytes(key.Substring(0, 8)); byte[] rgbIV = Keys; byte[] inputByteArray = Convert.FromBase64String(decryptString); DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length); cStream.FlushFinalBlock(); return Encoding.UTF8.GetString(mStream.ToArray()); } catch { return decryptString; } } public static string EncryptBase64(this string encryptString) { return Convert.ToBase64String(Encoding.UTF8.GetBytes(encryptString)); } public static string DecryptBase64(this string encryptString) { return Encoding.UTF8.GetString(Convert.FromBase64String(encryptString)); } public static string DecodeUrl(this string cryptString) { return System.Web.HttpUtility.UrlDecode(cryptString); } public static string EncodeUrl(this string cryptString) { return System.Web.HttpUtility.UrlEncode(cryptString); } } EncrypExtends
OK! 到此我们前题工作已经完成了80%,开始进行HTTP请求的 消息进和出的加密解密功能的实现.
我们暂时将加密的版本信息定义为 HTTP header头中 以 api_version 的value 来判别分别是用何种方式加密解密
header例:
api_version: 1.0
api_version: 1.1
/// <summary> /// API消息请求处理 /// </summary> public class JoyMessageHandler : MessageProcessingHandler { /// <summary> /// 接收到request时 处理 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, CancellationToken cancellationToken) { if (request.Content.IsMimeMultipartContent()) return request; // 获取请求头中 api_version版本号 var ver = System.Web.HttpContext.Current.Request.Headers.GetValues("api_version")?.FirstOrDefault(); // 根据api_version版本号获取加密对象, 如果为null 则不需要加密 var encrypt = MessageEncryptionCreator.GetInstance(ver); if (encrypt != null) { // 读取请求body中的数据 string baseContent = request.Content.ReadAsStringAsync().Result; // 获取加密的信息 // 兼容 body: 加密数据 和 body: code=加密数据 baseContent = baseContent.Match("(code=)*(?<code>[\\S]+)", 2); // URL解码数据 baseContent = baseContent.DecodeUrl(); // 用加密对象解密数据 baseContent = encrypt.Decode(baseContent); string baseQuery = string.Empty; if (!request.RequestUri.Query.IsNullOrEmpty()) { // 同 body // 读取请求 url query数据 baseQuery = request.RequestUri.Query.Substring(1); baseQuery = baseQuery.Match("(code=)*(?<code>[\\S]+)", 2); baseQuery = baseQuery.DecodeUrl(); baseQuery = encrypt.Decode(baseQuery); } // 将解密后的 URL 重置URL请求 request.RequestUri = new Uri($"{request.RequestUri.AbsoluteUri.Split('?')[0]}?{baseQuery}"); // 将解密后的BODY数据 重置 request.Content = new StringContent(baseContent); } return request; } /// <summary> /// 处理将要向客户端response时 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, CancellationToken cancellationToken) { //var isMediaType = response.Content.Headers.ContentType.MediaType.Equals(mediaTypeName, StringComparison.OrdinalIgnoreCase); var ver = System.Web.HttpContext.Current.Request.Headers.GetValues("api_version")?.FirstOrDefault(); var encrypt = MessageEncryptionCreator.GetInstance(ver); if (encrypt != null) { if (response.StatusCode == HttpStatusCode.OK) { var result = response.Content.ReadAsStringAsync().Result; // 返回消息 进行加密 var encodeResult = encrypt.Encode(result); response.Content = new StringContent(encodeResult); } } return response; } } JoyMessageHandler
最后在 webapiconfig 中将我们的消息处理添加到容器中