概述:
本代码是本人从c++代码上转换成的javascript代码,并测试验证通过的。考虑放其他地方要么要会员要么容易关闭,不容易被需要的获取到,故直接贴在本文档下面的章节,功能代码。
测试平台:
已经在如下环境中测试通过,其他平台(浏览器)应该也不会有问题:
1、nodejs中node.exe运行
2、微信小程序
功能代码:
function strDesCtxParams() {this.keybuf;this.keylen;
};var PC_1 = [ //PC_1置换57, 49, 41, 33, 25, 17, 9,1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15,7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4
];var Left_Move = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
];var PC_2 = [14, 17, 11, 24, 1, 5,3, 28, 15, 6, 21, 10,23, 19, 12, 4, 26, 8,16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55,30, 40, 51, 45, 33, 48,44, 49, 39, 56, 34, 53,46, 42, 50, 36, 29, 32
];var IP = [ //IP置换58, 50, 42, 34, 26, 18, 10, 2,60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6,64, 56, 48, 40, 32, 24, 16, 8,57, 49, 41, 33, 25, 17, 9, 1,59, 51, 43, 35, 27, 19, 11, 3,61, 53, 45, 37, 29, 21, 13, 5,63, 55, 47, 39, 31, 23, 15, 7
];var Extern = [ //扩展置换32, 1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1
];var IP_1 = [ //IP逆置换40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25
];var S_BOX = [ //S盒子/* S1 */14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,/* S2 */15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,/* S3 */10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,/* S4 */7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,/* S5 */2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,/* S6 */12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,/* S7 */4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,/* S8 */13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
];var P = [ //P置换16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25
];function des_init(keyArray, keyLen) {var i = 0;var desCtxParams = new strDesCtxParams();desCtxParams.keybuf = new Uint8Array(3 * (16 * 6));desCtxParams.keylen = keyLen;for (i = 0; i < keyLen; i += 8) {InputKey(keyArray, i, desCtxParams.keybuf, (16 * 6) * (i / 8));}//for (i = 0; i < 16 * 6 * 2; i++) {//console.log(i + " keybuf " + desCtxParams.keybuf[i]);//}return desCtxParams;
}function des_encrypt(desCtxParams, byteArrayDataIn) {return des_crypt(desCtxParams, byteArrayDataIn, true);
}function des_decrypt(desCtxParams, byteArrayDataIn) {return des_crypt(desCtxParams, byteArrayDataIn, false);
}function des_str_to_array(strIn) {var bytesArray = new Uint8Array(strIn.length);var i = 0;for (i = 0; i < strIn.length; i++) {bytesArray[i] = strIn.charCodeAt(i);}return bytesArray;
}function des_hex_to_array(hexStrIn) {var i = 0;var cnt = 0;var ele = 0;var bytesArray = null;cnt = 0;for (i = 0; i < hexStrIn.length; i++) {ele = hexStrIn.charCodeAt(i);if (ele >= 48 && ele < 48 + 10) {cnt++;}if (ele >= 65 && ele < 65 + 6) {cnt++;}if (ele >= 97 && ele < 97 + 6) {cnt++;}}bytesArray = new Uint8Array(parseInt((cnt + 1) / 2));cnt = 0;for (i = 0; i < hexStrIn.length; i++) {ele = hexStrIn.charCodeAt(i);if (ele >= 48 && ele < 48 + 10) {ele -= 48;cnt++;} else if (ele >= 65 && ele < 65 + 6) {ele = ele - 65 + 10;cnt++;} else if (ele >= 97 && ele < 97 + 6) {ele = ele - 97 + 10;cnt++;} else {continue;}if ((cnt % 2) == 1) {bytesArray[parseInt((cnt - 1) / 2)] = (ele << 4) & 0xF0;} else {bytesArray[parseInt((cnt - 1) / 2)] |= ele;}}return bytesArray;
}function des_hex_to_str(data, len) {var sha256_hex_digits = "0123456789abcdef";var output = new String();var i = 0;for (i = 0; i < len; i++) {output += sha256_hex_digits.charAt((data[i] >>> 4) & 0x0f);output += sha256_hex_digits.charAt((data[i]) & 0x0f);}return output;
}function Substitution(subIn, subLen, lpIn, lpInIndex, lpOut, lpOutIndex) {//置换var i = 0;for (i = 0; i < subLen; i++) {//console.log(i + " subIn = " + subIn[i]);if ((i % 8) == 0) {lpOut[parseInt(i / 8) + lpOutIndex] = 0x00;}/*if (i == 16) {console.log("lpInIndex:" + lpInIndex);console.log("subIn[i]:" + subIn[i]);console.log("parseInt((subIn[i] - 1) / 8) + lpInIndex :" + (((subIn[i] - 1) / 8) + lpInIndex));console.log("lpIn[parseInt((subIn[i] - 1) / 8) + lpInIndex] " + lpIn[parseInt((subIn[i] - 1) / 8) + lpInIndex]);return;}*/if ((lpIn[parseInt((subIn[i] - 1) / 8) + lpInIndex] & (0x80 >>> ((subIn[i] - 1) % 8))) != 0) {lpOut[parseInt(i / 8) + lpOutIndex] |= (0x80 >>> (i % 8));//console.log("in " + i);}//console.log(i + " lpOut :" + lpOut[parseInt(i / 8) + lpOutIndex]);}
}function LeftMove(buf, move) {var tmp;tmp = buf[0];buf[0] <<= move;buf[0] |= (buf[1] >> (8 - move));buf[1] <<= move;buf[1] |= (buf[2] >> (8 - move));buf[2] <<= move;buf[2] |= (buf[3] >> (8 - move));buf[3] &= 0xF0;buf[3] <<= move;buf[3] |= (tmp >> (8 - 4 - move));
}function des_crypt(desCtxParams, byteArrayDataIn, isEncrypt) {var outResult = new Uint8Array(8);var tmpBuf = null;if (desCtxParams.keylen == 8) {DesCode(byteArrayDataIn, 0, outResult, 0, isEncrypt, desCtxParams.keybuf, 0);}if (desCtxParams.keylen == 16) {tmpBuf = new Uint8Array(16);DesCode(byteArrayDataIn, 0, tmpBuf, 0, isEncrypt, desCtxParams.keybuf, 0);DesCode(tmpBuf, 0, tmpBuf, 8, !isEncrypt, desCtxParams.keybuf, 16 * 6);DesCode(tmpBuf, 8, outResult, 0, isEncrypt, desCtxParams.keybuf, 0);}if (desCtxParams.keylen == 24) {tmpBuf = new Uint8Array(16);DesCode(byteArrayDataIn, 0, tmpBuf, 0, isEncrypt, desCtxParams.keybuf, isEncrypt ? 0 : (16 * 6 * 2));DesCode(tmpBuf, 0, tmpBuf, 8, !isEncrypt, desCtxParams.keybuf, 16 * 6);DesCode(tmpBuf, 8, outResult, 0, isEncrypt, desCtxParams.keybuf, isEncrypt ? (16 * 6 * 2) : 0);}return outResult;
}function InputKey(keyIn, keyInOff, keyOutBuf, keyOutBufLen) {var tmpkey = new Uint8Array(32);var C = new Uint8Array(4);var D = new Uint8Array(4);var turns = 0;var i = 0;//console.log("keyInOff:" + keyInOff);Substitution(PC_1, 56, keyIn, keyInOff, tmpkey, 0);//console.log(des_hex(tmpkey, 32));for (turns = 0; turns < 16; turns++) {//memcpy(C, tmpkey, 4);//memcpy(D, &tmpkey[3], 4);for (i = 0; i < 4; i++) {C[i] = tmpkey[i];D[i] = tmpkey[i + 3];}D[0] <<= 4;D[0] &= 0xF0;D[0] |= ((D[1] >> 4) & 0x0F);D[1] <<= 4;D[1] &= 0xF0;D[1] |= ((D[2] >> 4) & 0x0F);D[2] <<= 4;D[2] &= 0xF0;D[2] |= ((D[3] >> 4) & 0x0F);D[3] <<= 4;D[3] &= 0xF0;LeftMove(C, Left_Move[turns]);LeftMove(D, Left_Move[turns]);//memcpy(tmpkey, C, 4);for (i = 0; i < 4; i++) {tmpkey[i] = C[i];}tmpkey[3] &= 0xF0;tmpkey[3] |= ((D[0] >> 4) & 0x0F);tmpkey[4] = (D[0] << 4) & 0xF0;tmpkey[4] |= ((D[1] >> 4) & 0x0F);tmpkey[5] = (D[1] << 4) & 0xF0;tmpkey[5] |= ((D[2] >> 4) & 0x0F);tmpkey[6] = (D[2] << 4) & 0xF0;tmpkey[6] |= ((D[3] >> 4) & 0x0F);//Substitution((unsigned char*)PC_2, 48, tmpkey, (unsigned char*)gTmpKey[turns]);Substitution(PC_2, 48,tmpkey, 0, keyOutBuf, keyOutBufLen + turns * 6);}//for (i = 0; i < 16 * 6; i++) {//console.log(i + " keybuf = %d",keyOutBuf[keyOutBufLen + i]);//}
}function DesCode(lpIn, lpInIndex, lpOut, lpOutIndex,isEncrypt /*true:加密;false:解密*/ , keybuf, keybufIndex) {//unsigned char tmp[64];var tmp = new Uint8Array(64);//char L[4];var L = new Uint8Array(4);//char R[4];var R = new Uint8Array(4);//char KeepR[4];var KeepR = new Uint8Array(4);var i = 0;var j = 0;var turns = 0;var tmpchar = 0;Substitution(IP, 64, lpIn, lpInIndex, tmp, 0); /*IP置换*///console.log(des_hex(tmp, 64));//memcpy(L, tmp, 4);//memcpy(R, &tmp[4], 4);for (i = 0; i < 4; i++) {L[i] = tmp[i];R[i] = tmp[i + 4];}if (isEncrypt) {turns = 0;} else {turns = 15;}while (true) {if (isEncrypt) {if (turns >= 16) {break;}} else {if (turns < 0) {break;}}//memcpy(KeepR, R, sizeof(R));for (i = 0; i < 4; i++) {KeepR[i] = R[i];}Substitution(Extern, 48, R, 0, tmp, 0);//console.log(des_hex(tmp, 64));//return;for (i = 0; i < 6; i++) {//tmp[i] = tmp[i] ^ gTmpKey[turns][i];tmp[i] = tmp[i] ^ keybuf[turns * 6 + i + keybufIndex];}//console.log(des_hex(tmp, 64));//return;/*S盒子计算*/for (i = 0; i < 8; i++) {/*8bit*6字节 转换成6bit*8字节*/tmpchar = tmp[parseInt(i * 6 / 8)];//console.log(parseInt(i * 6 / 8));//console.log("1:" + tmpchar);j = (i * 6) % 8;if (j > 2) {//两个字节tmpchar <<= (j - 2);tmpchar |= (tmp[parseInt(i * 6 / 8) + 1] >>> (10 - j));tmpchar &= 0x3F;} else {tmpchar >>>= (2 - j);tmpchar &= 0x3F;}//console.log("2:" + tmpchar);tmpchar |= ((tmpchar & 0x20) << 1);tmpchar &= (~0x20);tmpchar |= ((tmpchar & 0x01) << 5);tmpchar = (tmpchar >> 1) & 0x3F;//console.log("3:" + tmpchar);tmpchar = S_BOX[i * 64 + tmpchar];tmpchar &= 0x0F;//console.log("30:" + tmpchar);tmpchar = (tmpchar << (((i + 1) % 2) * 4));//console.log("4:" + tmpchar);tmp[parseInt(i / 2)] &= (0x0F << (((i) % 2) * 4));tmp[parseInt(i / 2)] |= tmpchar;//console.log(i + " tmp:" + tmp[parseInt(i / 2)]);//return;}//console.log(des_hex(tmp, 64));//return;Substitution(P, 32, tmp, 0, R, 0);for (j = 0; j < 4; j++) {R[j] ^= L[j]; /*异或运算*/L[j] = KeepR[j]; /*交换左右明文*/}/*合到一起*///memcpy(tmp, L, sizeof(L));//memcpy(tmp + 4, R, sizeof(R));for (i = 0; i < 4; i++) {tmp[i] = L[i];tmp[i + 4] = R[i];}if (isEncrypt) {turns++;} else {turns--;}}for (i = 0; i < 4; i++) {tmpchar = tmp[4 + i];tmp[4 + i] = tmp[i];tmp[i] = tmpchar;}/*IP的逆置换*/Substitution(IP_1, 64, tmp, 0, lpOut, lpOutIndex);
}module.exports = {des_init: des_init,des_encrypt: des_encrypt,des_decrypt: des_decrypt,des_str_to_array: des_str_to_array,des_hex_to_array: des_hex_to_array,des_hex_to_str: des_hex_to_str
}
测试代码:
如下在微信小程序中测试验证
var js_des = require('../../crypto/des.js');testDes() {var desCtx = null;var result = null;desCtx = js_des.des_init(js_des.des_hex_to_array("0011223344556677"), 8);result = js_des.des_encrypt(desCtx, js_des.des_hex_to_array("1234567890ABCDEF"));console.log("8B key des encrypt:" + js_des.des_hex_to_str(result, 8));desCtx = js_des.des_init(js_des.des_hex_to_array("00112233445566778888888800000000"), 16);result = js_des.des_encrypt(desCtx, js_des.des_hex_to_array("1234567890ABCDEF"));console.log("16B key des encrypt:" + js_des.des_hex_to_str(result, 8));desCtx = js_des.des_init(js_des.des_hex_to_array("0011223344556677888888880000000088776655AABBCCDD"), 24);result = js_des.des_encrypt(desCtx, js_des.des_hex_to_array("1234567890ABCDEF"));console.log("24B key des encrypt:" + js_des.des_hex_to_str(result, 8));desCtx = js_des.des_init(js_des.des_hex_to_array("0011223344556677"), 8);result = js_des.des_decrypt(desCtx, js_des.des_hex_to_array("1234567890ABCDEF"));console.log("8B key des decrypt:" + js_des.des_hex_to_str(result, 8));desCtx = js_des.des_init(js_des.des_hex_to_array("00112233445566778888888800000000"), 16);result = js_des.des_decrypt(desCtx, js_des.des_hex_to_array("1234567890ABCDEF"));console.log("16B key des decrypt:" + js_des.des_hex_to_str(result, 8));desCtx = js_des.des_init(js_des.des_hex_to_array("0011223344556677888888880000000088776655AABBCCDD"), 24);result = js_des.des_decrypt(desCtx, js_des.des_hex_to_array("1234567890ABCDEF"));console.log("24B key des decrypt:" + js_des.des_hex_to_str(result, 8));
},
测试结果:
8B key des encrypt:dabbb1cc478bffcc
16B key des encrypt:7bf2b53fc58f4069
24B key des encrypt:b2c9dae93ca6eb4b
79 8B key des decrypt:52832babfbd22b03
83 16B key des decrypt:3ad46435585e6d07
87 24B key des decrypt:8ebbe81aee99048c
经其他工具验证,结果是正确的