关于加密功能,客户端使用的是creator 用js开发的,服务器端用lua做的
- 要做加密功能: 1.利用c++绑定调用c++实现加密,
好处:调用同一种方法,一次实现
坏处:c++绑定只能用在原生系统,如果是浏览器端将无法使用加密功能
2.各自实现同一种算法
好处:各自实现,自己可以用任何方式实现
坏处:需要做到互相可以加解密
- 本次选择第二种方法:服务器用c++ 实现XXTea加密算法,客户端用js实现XXtea加密算法
过程: 客户端: XXTea加密 ----> base64编码 -----》send到服务器 -----》服务器先base64解码 -----》XXtea解密 ---->得到原始数据
base64编码是为了将加密过后的不可见的字符转化为可见的字符串 再发送 (不然服务器接收不到...)
客户端代码:
var TestXXTea = cc.Class({
extends: cc.Component,
statics: {
keyString: "]\743f8/hr34hLuH", //xxtea密钥 一般16位(也可以不是16位)
xxtea_encrypt: function (str) {
if (str == "") {
return "";
}
str = utf16ToUtf8(str); //如果是中文解析可能会出问题,加密之前先转化为utf8格式
var v = str2long(str, true);
var k = str2long(this.keyString, false);
if (k.length < 4) {
k.length = 4;
}
var n = v.length - 1;
var z = v[n], y = v[0], delta = 0x9E3779B9;
var mx, e, p, q = Math.floor(6 + 52 / (n + 1)), sum = 0;
while (0 < q--) {
sum = sum + delta & 0xffffffff;
e = sum >>> 2 & 3;
for (p = 0; p < n; p++) {
y = v[p + 1];
mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
z = v[p] = v[p] + mx & 0xffffffff;
}
y = v[0];
mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
z = v[n] = v[n] + mx & 0xffffffff;
}
str = long2str(v,false);
return encode_base64(str);//加密过后用base64编码
},
xxtea_decrypt: function (str) {
if (str == "") {
return "";
}
str = decode_base64(str)
var v = str2long(str, false);
var k = str2long(this.keyString, false);
if (k.length < 4) {
k.length = 4;
}
var n = v.length - 1;
var z = v[n], y = v[0], delta = 0x9E3779B9;
var mx, e, p, q = Math.floor(6 + 52 / (n + 1)), sum = q * delta & 0xffffffff;
while (sum != 0) {
e = sum >>> 2 & 3;
for (p = n; p > 0; p--) {
z = v[p - 1];
mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
y = v[p] = v[p] - mx & 0xffffffff;
}
z = v[n];
mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
y = v[0] = v[0] - mx & 0xffffffff;
sum = sum - delta & 0xffffffff;
}
var result = long2str(v,true);
result = utf8ToUtf16(result);
return result;
},
},
});
function utf16ToUtf8(str) { //utf16转化utf8 解决中文乱码问题
var out, i, len, c;
out = "";
len = str.length;
for (i = 0; i < len; i++) {
c = str.charCodeAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { out += str.charAt(i); } else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}
function utf8ToUtf16(str) {
var out, i, len, c;
var char2, char3;
out = "";
len = str.length;
i = 0;
while (i < len) {
c = str.charCodeAt(i++); switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += str.charAt(i - 1);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = str.charCodeAt(i++);
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = str.charCodeAt(i++);
char3 = str.charCodeAt(i++);
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}
function long2str(v, w) { //解密过程中将一个32位 数据转换成4个8位 的数据
var vl = v.length;
var n = (vl - 1) << 2;
if (w) {
var m = v[vl - 1];
if ((m < n - 3) || (m > n)) return null;
n = m;
}
for (var i = 0; i < vl; i++) {
v[i] = String.fromCharCode(v[i] & 0xff,
v[i] >> 8 & 0xff,
v[i] >> 16 & 0xff,
v[i] >> 24 & 0xff);
}
if (w) {
return v.join('').substring(0, n);
}
else {
return v.join('');
}
}
function str2long(s, w) { //加密过程中将4个8位的数据转化成一个32位的数据
var len = s.length;
var v = [];
for (var i = 0; i < len; i += 4) {
v[i >> 2] = s.charCodeAt(i)
| s.charCodeAt(i + 1) << 8
| s.charCodeAt(i + 2) << 16
| s.charCodeAt(i + 3) << 24;
}
if (w) {
v[v.length] = len;
}
return v;
}
function encode_base64(input) { //base64 编码
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
keyStr.charAt(enc1) +
keyStr.charAt(enc2) +
keyStr.charAt(enc3) +
keyStr.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
}
function decode_base64(input) { //base64解码
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;