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

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

用户密码这一块还算轻松,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解码-解压缩


你可能感兴趣的:(json,Ajax,C#,编码,安全)