您的位置:首页 > Web前端 > JavaScript

医调项目之C# 服务端与客户端JS通讯数据加密

2014-05-15 16:27 483 查看
前段时间做的一个项目需要进行安全评测,由于之前在代码安全性方面没有考虑太多。现在只好硬着头皮做好补救工作。

用户密码这一块还算轻松,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解码-解压缩
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: