服务器问答

求助一个前端加密后端解密的问题?
0
1975-02-20 03:16:34
idczone

本人菜鸟一枚,今天做模拟登录遇到了一个前端加密后端解密的问题,自己根据谷歌搜索出来的代码片段倒腾了一个上午也没搞出来,所以这只能厚着脸皮来这里问大佬们了,下面这个 JavaScript 编码函数编码后的字符串,在后端如何用 php 解码出来提交的字符串。

如果问题太低端,望大佬们别怼我,真心求助,求大佬们不吝赐教!

function Ye() {
	return 256 * Math.random() | 0
}
var rn = [3, 7];
function on(e, t) {
	void 0 === t && (t = Ye);
	var n = t() % 4,
		r = function(e) {
			if ("fu美国服务器nction" == typeof TextEncoder){
				return (new TextEncoder).encode(e);
			}
			for (var t = unescape(encodeURI(e)), n = new Uint8Array(t.length), r = 0; r < t.length; ++r)
				n[r] = t.charCodeAt(r);
			return n
		}(JSON.stringify(e));
	console.log("17",r);
	var i = 1 + rn.length + 1 + n + 7 + r.length;
		console.log("19",t.length,rn.length,n,r.length,i);
	var o = new ArrayBuffer(i);
		console.log("21",o)
	var a = new Uint8Array(o)
	  , u = 0
	  , s = t();
	a[u++] = s;
	for (var c = 0, l = rn; c < l.length; c++) {
		var d = l[c];
		a[u++] = s + d
	}
	a[u++] = s + n;
	for (var f = 0; f < n; ++f)
		a[u++] = t();
	var v = new Uint8Array(7);
	for (f = 0; f < 7; ++f)
		v[f] = t(),
		a[u++] = v[f];
	for (f = 0; f < r.length; ++f)
		a[u++] = r[f] ^ v[f % 7];
	console.log("39",o);
	return o
}

on('{"name":"abcde","password":"15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225"}')


没看代码,单纯搜索了一下 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225
https://md5calc.com/hash/sha256/123456789

哦,我看错了,还以为 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 是编码后的结果 hhhh

on('{"name":"abcde","password":"15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225"}')
%7B%22name%22:%22abcde%22,%22password%22:%2215e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225%22%7D

开局的 void 0 === t && (t = Ye);
t() 就是随机数了,n 就是 0~3 之间的随机数了
原始字符串:
{"name":"abcde","password":"15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225"}
长度 94
先 stringify,
"{\"name\":\"abcde\",\"password\":\"15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225\"}"
长度 104
然后逐个 charCodeAt:
[34,123,92,34,110,97,109,101,92,34,58,92,34,97,98,99,100,101,92,34,44,92,34,112,97,115,115,119,111,114,100,92,34,58,92,34,49,53,101,50,98,48,100,51,99,51,51,56,57,49,101,98,98,48,102,49,101,102,54,48,57,101,99,52,49,57,52,50,48,99,50,48,101,51,50,48,99,101,57,52,99,54,53,102,98,99,56,99,51,51,49,50,52,52,56,101,98,50,50,53,92,34,125,34]
长度 104
console.log("17",r);

var i = 1 + rn.length + 1 + n + 7 + r.length;
i 不知道干啥的,先不管
然后初始化了 o a
u = 0,s = 随机数
for (var c = 0, l = rn; c < l.length; c++) {
var d = l[c];
a[u++] = s + d
}

a[u++] = s; 也就是 a[0]=s, u=1

for (var c = 0, l = rn; c < l.length; c++) {
var d = l[c];
a[u++] = s + d
}
也就是把 a[1] a[2] 赋值为 s + rn[1,2]
a[u++] = s + n;

把 a[3] 赋值为 s + n
for (var f = 0; f < n; ++f)
a[u++] = t();
把 a[4]~a[3+n-1] 赋值为随机数
for (f = 0; f < 7; ++f)
v[f] = t(),
a[u++] = v[f];
弄 7 个随机数放进 a[...]
for (f = 0; f < r.length; ++f)
a[u++] = r[f] ^ v[f % 7];
对应这 7 个随机数,对 r 做异或

解码,只需要反向来就好:
a[0]=s
a[1,2] 是 a + rn[0,1]
a[3] 是 s+n
接下来有 n 个随机数
接下来有 7 个随机数
剩下的都是原始数据了
把原始数据逐个和 7 个随机数异或,就得到 byte array 了,然后自行转码回去就行

不懂算法 只会用现成的库
两个问题
1. 既然有 js 加密的方法 那应该有 js 解密的方法 先用 js 解密再说
2. 前端的加密解密方法是哪来的
估计大部分人应该都是 copy boy 知道来源
换个语言 同样的加密解密 网上应该大把的代码
就算这个加密方案是前端自己写的 协商下网上找个相同的加密方式不是更简单

x 谢谢大佬指点,不过还是云里雾里的,只怪太菜了。


4 楼第二句写错了,应该是:
a[1,2] 是 s + rn[0,1]

反正就是你拿到的数组 a,先把 a[0] 取出来,是 s
然后把 a[3] 取出来,是 n + s,求出 n
然后从 a[3+n+1] 开始,到 a[3+n+7],是异或的随机数
rn 这个数组看起来好像没用

大佬,按你说的方法一步一步搞下去也没搞出来,可耻的问一句能做个伸手党嘛?

连是什么算法都不知道,就别折腾了。
对称加密用 https://github.com/brix/crypto-js,PHP 解密用 openssl_decrypt
非对称加密用 https://github.com/travist/jsencrypt,PHP 解密用 openssl_private_decrypt

真让人头大……你先搞清楚加密协议

同意 9 楼,如果是为了实现功能建议直接用现有的轮子,比自己写的要好到不知哪儿去。

感觉大佬的指点,已经解码出来了。

搞个 wasm 的,随便一个可逆加密算法像 Aes256 这些,后端一调对应算法的库就可以了,为什么要手动写?不嫌弃麻烦啊?


OK,这个算法其实不难 ,多点耐心就好~

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服