医调项目之C# 服务端与客户端JS通讯数据加密
2014-05-15 16:27
483 查看
前段时间做的一个项目需要进行安全评测,由于之前在代码安全性方面没有考虑太多。现在只好硬着头皮做好补救工作。
用户密码这一块还算轻松,MD5加密放入数据库中就没啥问题了。
关键是这个项目服务端和客户端通讯用的是ajax,数据格式是JSON,而且全部是明文。这种情况拿去评测摆明了通不过啊。无奈只好去网上找找有没有现成的代码。
服务端还好说,用.net自带的压缩函数DeflateStream处理之后再进行BASE64编码就可以了。
服务端压缩+BASE64编码:
剩下的就是客户端JS部分了。
首先要进行BASE64解码,然后再解压缩。这里需要注意的是在进行BASE64解码的时候必须进一步调用UTF8To16()这个JS方法,否则可能会出现中文乱码的情况。
JS解压缩调用的是网上的一个JS脚本。不过我在这里吃了一个大亏,花了好长时间才算搞清楚。网上的代码基本上都是这样:utf8to16(zip_depress(base64decode(sRtn)))
utf8to16和base64decode 相信大家都能理解。可是最关键的解压缩函数被人改了函数名,后来也有人发现了这个问题,不过她没有把原来的函数名给写出来,导致我花了不少时间。实际上zip_depress这个函数的函数原名是 zip_inflate 。
BASE64解码:
JS 解压缩:
JS脚本下载地址
最后附上我的demo代码
服务端:
客户端:
用户密码这一块还算轻松,MD5加密放入数据库中就没啥问题了。
关键是这个项目服务端和客户端通讯用的是ajax,数据格式是JSON,而且全部是明文。这种情况拿去评测摆明了通不过啊。无奈只好去网上找找有没有现成的代码。
服务端还好说,用.net自带的压缩函数DeflateStream处理之后再进行BASE64编码就可以了。
服务端压缩+BASE64编码:
/// <summary> /// Deflate压缩函数 /// </summary> /// <param name="strSource"></param> /// <returns></returns> public static string DeflateCompress(string strSource) { if (strSource == null || strSource.Length > 800 * 1024) throw new System.ArgumentException("字符串为空或长度太大!"); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strSource); using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { using (DeflateStream stream = new DeflateStream(ms, CompressionMode.Compress, true)) { stream.Write(buffer, 0, buffer.Length); stream.Close(); } //using (GZipStream gZipStream = new GZipStream(ms, CompressionMode.Compress)) //{ // gZipStream.Write(buffer, 0, buffer.Length); // gZipStream.Close(); //} byte[] compressedData = ms.ToArray(); ms.Close(); return Convert.ToBase64String(compressedData); //将压缩后的byte[]转换为Base64String } }
剩下的就是客户端JS部分了。
首先要进行BASE64解码,然后再解压缩。这里需要注意的是在进行BASE64解码的时候必须进一步调用UTF8To16()这个JS方法,否则可能会出现中文乱码的情况。
JS解压缩调用的是网上的一个JS脚本。不过我在这里吃了一个大亏,花了好长时间才算搞清楚。网上的代码基本上都是这样:utf8to16(zip_depress(base64decode(sRtn)))
utf8to16和base64decode 相信大家都能理解。可是最关键的解压缩函数被人改了函数名,后来也有人发现了这个问题,不过她没有把原来的函数名给写出来,导致我花了不少时间。实际上zip_depress这个函数的函数原名是 zip_inflate 。
BASE64解码:
String.prototype.UTF16To8 = function () { var str = this; var ret = "", i, len, charCode; len = str.length; for (i = 0; i < len; i++) { charCode = str.charCodeAt(i); if ((charCode >= 0x0001) && (charCode <= 0x007F)) { ret += str.charAt(i); } else if (charCode > 0x07FF) { ret += String.fromCharCode(0xE0 | ((charCode >> 12) & 0x0F)); ret += String.fromCharCode(0x80 | ((charCode >> 6) & 0x3F)); ret += String.fromCharCode(0x80 | ((charCode >> 0) & 0x3F)); } else { ret += String.fromCharCode(0xC0 | ((charCode >> 6) & 0x1F)); ret += String.fromCharCode(0x80 | ((charCode >> 0) & 0x3F)); } } return ret; } String.prototype.UTF8To16 = function () { var str = this; var ret = "", i = 0, len, charCode; var charCode2, charCode3; len = str.length; while (i < len) { charCode = str.charCodeAt(i++); switch (charCode >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: ret += str.charAt(i - 1); break; case 12: case 13: charCode2 = str.charCodeAt(i++); ret += String.fromCharCode(((charCode & 0x1F) << 6) | (charCode2 & 0x3F)); break; case 14: charCode2 = str.charCodeAt(i++); charCode3 = str.charCodeAt(i++); ret += String.fromCharCode(((charCode & 0x0F) << 12) | ((charCode2 & 0x3F) << 6) | ((charCode3 & 0x3F) << 0)); break; } } return ret; } String.prototype.EncodeBase64 = function () { var str = this; str = str.UTF16To8(); var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var ret = "", i = 0, len; var charCode1, charCode2, charCode3; len = str.length; while (i < len) { charCode1 = str.charCodeAt(i++) & 0xff; if (i == len) { ret += base64EncodeChars.charAt(charCode1 >> 2); ret += base64EncodeChars.charAt((charCode1 & 0x3) << 4); ret += "=="; break; } charCode2 = str.charCodeAt(i++); if (i == len) { ret += base64EncodeChars.charAt(charCode1 >> 2); ret += base64EncodeChars.charAt(((charCode1 & 0x3) << 4) | ((charCode2 & 0xF0) >> 4)); ret += base64EncodeChars.charAt((charCode2 & 0xF) << 2); ret += "="; break; } charCode3 = str.charCodeAt(i++); ret += base64EncodeChars.charAt(charCode1 >> 2); ret += base64EncodeChars.charAt(((charCode1 & 0x3) << 4) | ((charCode2 & 0xF0) >> 4)); ret += base64EncodeChars.charAt(((charCode2 & 0xF) << 2) | ((charCode3 & 0xC0) >> 6)); ret += base64EncodeChars.charAt(charCode3 & 0x3F); } return ret; } String.prototype.DecodeBase64 = function () { var str = this; str = str.UTF16To8(); var base64DecodeChars = new Array( -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1); var charCode1, charCode2, charCode3, charCode4; var ret = "", i = 0, len; len = str.length; while (i < len) { do { charCode1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; } while (i < len && charCode1 == -1); if (charCode1 == -1) break; do { charCode2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; } while (i < len && charCode2 == -1); if (charCode2 == -1) break; ret += String.fromCharCode((charCode1 << 2) | ((charCode2 & 0x30) >> 4)); do { charCode3 = str.charCodeAt(i++) & 0xff; if (charCode3 == 61) return ret; charCode3 = base64DecodeChars[charCode3]; } while (i < len && charCode3 == -1); if (charCode3 == -1) break; ret += String.fromCharCode(((charCode2 & 0XF) << 4) | ((charCode3 & 0x3C) >> 2)); do { charCode4 = str.charCodeAt(i++) & 0xff; if (charCode4 == 61) return ret; charCode4 = base64DecodeChars[charCode4]; } while (i < len && charCode4 == -1); if (charCode4 == -1) break; ret += String.fromCharCode(((charCode3 & 0x03) << 6) | charCode4); } return ret; }
JS 解压缩:
JS脚本下载地址
最后附上我的demo代码
服务端:
sRtnContent = Comn.DeflateCompress(sRtnContent);
客户端:
zip_inflate(sRtn.DecodeBase64()).UTF8To16(); //BASE64解码-解压缩
相关文章推荐
- 【推荐】捕获WCF服务端与客户端产生的通讯数据并分析
- JST+JSON+AJAX——使用客户端js模版代替服务端数据绑定
- JST+JSON+AJAX——使用客户端js模版代替服务端数据绑定
- C# TCP实现多个客户端与服务端 数据 与 文件的传输
- 客户端JavaScript加密数据,服务端Java解密数据
- RSA客户端js加密服务器C#解密(含源码)
- 基于RSA算法的ios客户端加密和C#服务端解密的解决方案
- JS客户端RSA加密,Java服务端解密
- 基于RSA算法的ios客户端加密和C#服务端解密的解决方案
- node.js版简单客户端和服务端通讯源码
- 【推荐】捕获WCF服务端与客户端产生的通讯数据并分析
- [转载]C# TCP实现多个客户端与服务端 数据 与 文件的传输
- C#客户端和服务端数据的同步传输
- RSA客户端js加密服务器C#解密(含源码)
- C# 实现 客户端 对实时数据的采集 上传至服务端;在服务端把保存到内存中;供WEB页面调用
- 服务端数据校验及客户端js脚本验证集成处理初探(附源码)
- 【推荐】捕获WCF服务端与客户端产生的通讯数据并分析
- RSA和AES在c#服务端和android客户端之间的加密解密
- Android 对Android客户端与服务端传递的Json数据进行加密、解密操作
- JST+JSON+AJAX——使用客户端js模版代替服务端数据绑定