声明:该专栏涉及的所有案例均为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖!
文章目录
一、前言
看看西红柿
二、【2023-02-24】版本
网址:
aHR0cHM6Ly93d3cueGlhb2hvbmdzaHUuY29tL2V4cGxvcmU=
1.网站分析
打开一篇文章,查看下请求参数有x-s和x-t
还有cookie中有个web_session
2.参数x-s
全局搜索,很容易定位到
直接断点运行,抠下sign函数
缺什么补什么,大概补三个函数
运行报错,经过和浏览器对比,浏览器生成数组,而webstorm中报错
然后发现r和浏览器中不同
而r = a0_0x543e();
,因此我们直接把这个列表替换成a0_0x543e的返回内容
再运行
补window
缺MD5
补上运行
3.web_session
而cookie中的web_session,我们将application中的这个值删掉,再刷新,就能拿到注册该cookie的接口
4.测试
合起来看一下文章,成功
三、【2024-06-03】 版本
我们抓包文章后,看到里面有x-s,x-s-common,x-t参数,这里我们分析x-s。
看到x-s后边的编码像base64,试一下
看到这里只要搞清楚payload是怎么来的就行。
1. 抓包流程
我们全局搜索x-s,找到这里
我们这里研究文章,所以下个文章的条件断点
然后开始下断,断住后,进入到里面,就会看到vmp,这里最终返回了x-s
调一下,经过亿点点循环,最后返回了x-s
2.简单分析下jsvmp文件
上边提到了vmp,这里简单说下jsvmp。
在JSVMP逆向分析中,寄存器,循环是重要的特征,还有有一个特性,加密结果是一个一个字符生成的,基本由一个循环就是for循环或者while循环以及switch case控制。这一点至关重要,算法的分析还原就依赖这个特性。
JSVMP,一般在代码中会有一个超长字符串(指令),然后会把这个字符串decode成一个大数组,不断循环从数组中取指令,分配函数执行运算操作,运算过程会在一个数组或者对象中不断放进或取出生成的值,最后生成目标结果,这个过程会有+,/,%,*操作,会有个apply操作,这些都是插桩的关键位置。
我们通常对vmp的做法就是这么几种:
- rpc
- 逆向算法
- 补环境
这里我们采用逆向算法,那么就得进行插桩打日志了。把这个vmp文件复制下来放到notepad里看一下,由于内容比较小,大概看一下流程
简单的分析下,刚才我们分析payload是对base64解码,先看返回值
- 2中的的参数像上找执行了deceode,1是对decode的执行
- 2最终返回值执行的是这个
_ace_99485函数
- 3是
_ace_99485函数
,按照jsvmp执行是个循环来说,该函数应该是个循环函数
这个循环实际上一直执行的是_ace_416e1
函数和7个参数,下边的一些函数应该都是指令集,就是决定执行哪个函数
我们依次网上找一下这个主循环执行的方式,一步一步往上找
_ace_416e1 >>> _ace_aec23 >>> _ace_1ae3c >>> _ace_b81ca
3.插桩
我们大概看明白这个流程,再看一下指令集,大多数是对_ace_1ae3c
进行的操作
那么我们就在这些有计算符号的日志断点试试,这个是拼接的比较重要
日志断点几十万行,容易卡死浏览器,最好一个一个打。或者就是本地js替换一下,定义全局变量,最后copy下来日志到文本中看。
接下来看日志。
首先看到日志的url和他的参数拼接
然后往下看到x1,x2,x3,x4拼接的字符串
- x1值就是,刚才url和好他参数拼接值的md5
- x2是环境值,这里我们固定
- x3是cookie中的a1值
- x4是时间戳
拼接完该值,继续看日志,发现了一串base64,试了一下是对x1-x4值拼接出来base64。
再然后是对这个base64值再进行了一次加密,然后得到了payload。
看到这里生成了一开始我们解开的那个base64。中间没有找到payload是怎么生成的。
{"signSvn":"51","signType":"x1","appId":"xhs-pc-web","signVersion":"1","payload":"37b725ee4f04c180f0ff8e4f16b1c844319bbbed853da6d24e19e1e047500a3c382703f45f66f348cb47eb335cf94709c9e3bfda1faa1eb90d74aa31b54c72cd0d74aa31b54c72cdac489b9da8ce5e48f4afb9acfc3ea26fe0b266a6b4cc3cb52b9fa8540f12a90c30bdf5b8f7275117e29d380b88d5d3d18d5a29b89a8429cccd2451f5ca2f66ada151065790b0b99972fbca2a586c2af1c502dc5c4b83c1bd872cc1f0a90d588f1be60173968a5dc4a39979bf3fbae5fe1dcbcaaca46f5bae"}
但是日志里没有找到payload是怎么生成的。说明这个插桩点看不到怎么加密了。
该换地方插桩了
回到刚才会知道最后都走这里,那么我们依次把这4个参数输出,测试了一下,只有第二个参数有用
那么只对第二个参数输出,直接输出了一次浏览器卡死了,把干扰项Q开始的队列过滤一下,最好还是替换输出到本地,电脑不太行,老卡死
if (_ace_7e97a && _ace_7e97a[0] != 'Q' && _ace_7e97a[1] != "implementation") {
try {
console.log(JSON.stringify(_ace_7e97a))
} catch (e) {
}
}
然后看日志,紧接着找到刚才payload生成出来前的地方,看到包含这么一个数组值,百度上一搜是DES加密
那么需要找找key值,一般为16或者32位,在他周围有个数组是32的长度,就是密钥
找了个des的js版本代码改改,用日志的值验证一下,和日志里的一样!
生成出这个以后,再base64
{"signSvn":"51","signType":"x1","appId":"xhs-pc-web","signVersion":"1","payload":"a34eba1cac322a614c17453e2d9d529cf0d9c5e1e922cf1eec90561f2a9c7719c522c38dffcc733edacf5be1949c1baac9e3bfda1faa1eb90d74aa31b54c72cd0d74aa31b54c72cdac489b9da8ce5e48f4afb9acfc3ea26fe0b266a6b4cc3cb52b9fa8540f12a90c30bdf5b8f7275117e29d380b88d5d3d18d5a29b89a8429cccd2451f5ca2f66ada151065790b0b99972fbca2a586c2af1c502dc5c4b83c1bd872cc1f0a90d588fb6ce674244e11e7c87f22c522da8e733c44ef899051334f9"}
最后和XYW_拼接得到x-s,拼装代码试一下
4.des的代码
有好多小伙伴找不到这个des代码,这里放一下,key直接在上边15行写死成xhs的了
// https://github.com/liasica/desjs/blob/master/src/index.ts
function des(key, message, encrypt, mode, iv, padding) {
//declaring this locally speeds things up a bit
var spfunction1 = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004);
var spfunction2 = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000);
var spfunction3 = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200);
var spfunction4 = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080);
var spfunction5 = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100);
var spfunction6 = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010);
var spfunction7 = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002);
var spfunction8 = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000);
//create the 16 or 48 subkeys we will need
// var keys = des_createKeys(key);
var keys = [187050025, 472920585, 186915882, 876157969, 255199502, 806945584, 220596020, 958210835, 757275681, 940378667, 489892883, 705504304, 354103316, 688857884, 890312192, 219096591, 622400037, 254088489, 907618332, 52759587, 907877143, 53870614, 839463457, 389417746, 975774727, 372382245, 437136414, 909246726, 168694017, 473575703, 52697872, 1010440969];
var m = 0, i, j, temp, temp2, right1, right2, left, right, looping;
var cbcleft, cbcleft2, cbcright, cbcright2
var endloop, loopinc;
var len = message.length;
var chunk = 0;
//set up the loops for single and triple des
var iterations = keys.length == 32 ? 3 : 9; //single or triple des
if (iterations == 3) {
looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2);
} else {
looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2);
}
//pad the message depending on the padding parameter
if (padding == 2) message += " "; //pad the message with spaces
else if (padding == 1) {
temp = 8 - (len % 8);
message += String.fromCharCode(temp, temp, temp, temp, temp, temp, temp, temp);
if (temp == 8) len += 8;
} //PKCS7 padding
else if (!padding) message += "\0\0\0\0\0\0\0\0"; //pad the message out with null bytes
//store the result here
var result = "";
var tempresult = "";
if (mode == 1) {
//CBC mode
cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
m = 0;
}
//loop through each 64 bit chunk of the message
while (m < len) {
left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
//for Cipher Block Chaining mode, xor the message with the previous result
if (mode == 1) {
if (encrypt) {
left ^= cbcleft;
right ^= cbcright;
} else {
cbcleft2 = cbcleft;
cbcright2 = cbcright;
cbcleft = left;
cbcright = right;
}
}
//first each 64 but chunk of the message must be permuted according to IP
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
right ^= temp;
left ^= (temp << 4);
temp = ((left >>> 16) ^ right) & 0x0000ffff;
right ^= temp;
left ^= (temp << 16);
temp = ((right >>> 2) ^ left) & 0x33333333;
left ^= temp;
right ^= (temp << 2);
temp = ((right >>> 8) ^ left) & 0x00ff00ff;
left ^= temp;
right ^= (temp << 8);
temp = ((left >>> 1) ^ right) & 0x55555555;
right ^= temp;
left ^= (temp << 1);
left = ((left << 1) | (left >>> 31));
right = ((right << 1) | (right >>> 31));
//do this either 1 or 3 times for each chunk of the message
for (j = 0; j < iterations; j += 3) {
endloop = looping[j + 1];
loopinc = looping[j + 2];
//now go through and perform the encryption or decryption
for (i = looping[j]; i != endloop; i += loopinc) {
//for efficiency
right1 = right ^ keys[i];
right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1];
//the result is attained by passing these bytes through the S selection functions
temp = left;
left = right;
right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f]
| spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f]
| spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f]
| spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
}
temp = left;
left = right;
right = temp; //unreverse left and right
} //for either 1 or 3 iterations
//move then each one bit to the right
left = ((left >>> 1) | (left << 31));
right = ((right >>> 1) | (right << 31));
//now perform IP-1, which is IP in the opposite direction
temp = ((left >>> 1) ^ right) & 0x55555555;
right ^= temp;
left ^= (temp << 1);
temp = ((right >>> 8) ^ left) & 0x00ff00ff;
left ^= temp;
right ^= (temp << 8);
temp = ((right >>> 2) ^ left) & 0x33333333;
left ^= temp;
right ^= (temp << 2);
temp = ((left >>> 16) ^ right) & 0x0000ffff;
right ^= temp;
left ^= (temp << 16);
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
right ^= temp;
left ^= (temp << 4);
//for Cipher Block Chaining mode, xor the message with the previous result
if (mode == 1) {
if (encrypt) {
cbcleft = left;
cbcright = right;
} else {
left ^= cbcleft2;
right ^= cbcright2;
}
}
tempresult += String.fromCharCode((left >>> 24), ((left >>> 16) & 0xff), ((left >>> 8) & 0xff), (left & 0xff), (right >>> 24), ((right >>> 16) & 0xff), ((right >>> 8) & 0xff), (right & 0xff));
chunk += 8;
if (chunk == 512) {
result += tempresult;
tempresult = "";
chunk = 0;
}
} //for every 8 characters, or 64 bits in the message
//return the result as an array
return result + tempresult;
} //end of des
//des_createKeys
//this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 integers, and returns 16 48 bit keys
function des_createKeys(key) {
//declaring this locally speeds things up a bit
var pc2bytes0 = new Array(0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204, 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204);
var pc2bytes1 = new Array(0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100, 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101);
var pc2bytes2 = new Array(0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808);
var pc2bytes3 = new Array(0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000, 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000);
var pc2bytes4 = new Array(0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000, 0x41000, 0x1010, 0x41010);
var pc2bytes5 = new Array(0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420, 0x2000000, 0x2000400, 0x2000020, 0x2000420);
var pc2bytes6 = new Array(0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002);
var pc2bytes7 = new Array(0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000, 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800);
var pc2bytes8 = new Array(0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000, 0x2000002, 0x2040002, 0x2000002, 0x2040002);
var pc2bytes9 = new Array(0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408, 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408);
var pc2bytes10 = new Array(0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020, 0x102000, 0x102020, 0x102000, 0x102020);
var pc2bytes11 = new Array(0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000, 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200);
var pc2bytes12 = new Array(0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010, 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010);
var pc2bytes13 = new Array(0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105);
//how many iterations (1 for des, 3 for triple des)
var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
//stores the return keys
var keys = new Array(32 * iterations);
//now define the left shifts which need to be done
var shifts = new Array(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
//other variables
var lefttemp, righttemp, m = 0, n = 0, temp, left, right;
for (var j = 0; j < iterations; j++) {
//either 1 or 3 iterations
left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
right ^= temp;
left ^= (temp << 4);
temp = ((right >>> -16) ^ left) & 0x0000ffff;
left ^= temp;
right ^= (temp << -16);
temp = ((left >>> 2) ^ right) & 0x33333333;
right ^= temp;
left ^= (temp << 2);
temp = ((right >>> -16) ^ left) & 0x0000ffff;
left ^= temp;
right ^= (temp << -16);
temp = ((left >>> 1) ^ right) & 0x55555555;
right ^= temp;
left ^= (temp << 1);
temp = ((right >>> 8) ^ left) & 0x00ff00ff;
left ^= temp;
right ^= (temp << 8);
temp = ((left >>> 1) ^ right) & 0x55555555;
right ^= temp;
left ^= (temp << 1);
//the right side needs to be shifted and to get the last four bits of the left side
temp = (left << 8) | ((right >>> 20) & 0x000000f0);
//left needs to be put upside down
left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
right = temp;
//now go through and perform these shifts on the left and right keys
for (var i = 0; i < shifts.length; i++) {
//shift the keys either one or two bits to the left
if (shifts[i]) {
left = (left << 2) | (left >>> 26);
right = (right << 2) | (right >>> 26);
} else {
left = (left << 1) | (left >>> 27);
right = (right << 1) | (right >>> 27);
}
left &= -0xf;
right &= -0xf;
//now apply PC-2, in such a way that E is easier when encrypting or decrypting
//this conversion will look like PC-2 except only the last 6 bits of each byte are used
//rather than 48 consecutive bits and the order of lines will be according to
//how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf]
| pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf]
| pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf]
| pc2bytes6[(left >>> 4) & 0xf];
righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf]
| pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf]
| pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf]
| pc2bytes13[(right >>> 4) & 0xf];
temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
keys[n++] = lefttemp ^ temp;
keys[n++] = righttemp ^ (temp << 16);
}
} //for each iterations
//return the keys we've created
return keys;
} //end of des_createKeys
// enum Padding {
// NULL = 0,
// PKCS7 = 1,
// SPACES = 2,
// NONE = 3
// }
//
// enum Mode {
// ECB = 0,
// CBC = 1
// }
//
var encodeHex = function (s) {
let r = '';
const hexes = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
for (let i = 0; i < s.length; i++) {
r += hexes [s.charCodeAt(i) >> 4] + hexes [s.charCodeAt(i) & 0xf];
}
return r;
};
var decodeHex = function (h) {
let r = '';
for (let i = (h.substring(0, 2) === '0x') ? 2 : 0; i < h.length; i += 2) {
r += String.fromCharCode(parseInt(h.substring(i, i + 2), 16));
}
return r;
};
function get_des(message) {
return encodeHex(des(undefined, message, 1, 0, undefined, 0));
}
//
// export const encrypt = (key: string, message: string, iv?: string, padding: Padding = Padding.NONE): string => {
// const mode = iv ? Mode.CBC : Mode.ECB
// return encodeHex(des(key, message, 1, mode, iv, padding))
// }
//
// export const decrypt = (key: string, message: string, iv?: string, padding: Padding = Padding.NONE) => {
// const mode = iv ? Mode.CBC : Mode.ECB
// return des(key, decodeHex(message), 0, mode, iv, padding).replace(/\0/g, '')
// }
// 加密测试
var message = "eDE9NzIxYjdjODRjNWJkYmY3ZjUxYTZkMmNhYTEyZjhiNDQ7eDI9MHwwfDB8MXwwfDB8MXwwfDB8MHwxfDB8MHwwfDA7eDM9MThmYmUyNDAyYTZvNWl5c3prd29uMWl2NmduMGFkOHE2NHJiOGUyeW81MDAwMDI2ODI4MTt4ND0xNzE3MDM3Mjc2OTY1Ow==";
var aaa = encodeHex(des(undefined, message, 1, 0, undefined, 0));
console.log(aaa);
// 解密测试
// aaa='a34eba1cac322a614c17453e2d9d529cf0d9c5e1e922cf1eec90561f2a9c7719c522c38dffcc733edacf5be1949c1baac9e3bfda1faa1eb90d74aa31b54c72cd0d74aa31b54c72cdac489b9da8ce5e48f4afb9acfc3ea26fe0b266a6b4cc3cb52b9fa8540f12a90c30bdf5b8f7275117e29d380b88d5d3d18d5a29b89a8429cccd2451f5ca2f66ada151065790b0b99972fbca2a586c2af1c502dc5c4b83c1bd872cc1f0a90d588fb6ce674244e11e7c87f22c522da8e733c44ef899051334f9'
// var result = des(undefined, decodeHex(aaa), 0, 0, undefined, 0).replace(/\0/g, '');
// console.log(result);
文章评论