V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ZiShuo
V2EX  ›  PHP

求助一个前端加密后端解密的问题?

  •  
  •   ZiShuo · 2021-04-18 14:33:19 +08:00 · 3109 次点击
    这是一个创建于 1349 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人菜鸟一枚,今天做模拟登录遇到了一个前端加密后端解密的问题,自己根据谷歌搜索出来的代码片段倒腾了一个上午也没搞出来,所以这只能厚着脸皮来这里问大佬们了,下面这个 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 ("function" == 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"}')
    
    14 条回复    2021-04-19 16:26:26 +08:00
    also24
        1
    also24  
       2021-04-18 14:38:36 +08:00
    没看代码,单纯搜索了一下 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225

    https://md5calc.com/hash/sha256/123456789
    also24
        2
    also24  
       2021-04-18 14:41:08 +08:00
    哦,我看错了,还以为 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 是编码后的结果 hhhh
    also24
        3
    also24  
       2021-04-18 15:14:30 +08:00
    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 做异或
    also24
        4
    also24  
       2021-04-18 15:17:15 +08:00
    解码,只需要反向来就好:

    a[0]=s
    a[1,2] 是 a + rn[0,1]
    a[3] 是 s+n
    接下来有 n 个随机数
    接下来有 7 个随机数
    剩下的都是原始数据了

    把原始数据逐个和 7 个随机数异或,就得到 byte array 了,然后自行转码回去就行
    cs419
        5
    cs419  
       2021-04-18 15:28:31 +08:00
    不懂算法 只会用现成的库
    两个问题
    1. 既然有 js 加密的方法 那应该有 js 解密的方法 先用 js 解密再说
    2. 前端的加密解密方法是哪来的
    估计大部分人应该都是 copy boy 知道来源
    换个语言 同样的加密解密 网上应该大把的代码

    就算这个加密方案是前端自己写的 协商下网上找个相同的加密方式不是更简单
    ZiShuo
        6
    ZiShuo  
    OP
       2021-04-18 16:35:04 +08:00
    @also24 x 谢谢大佬指点,不过还是云里雾里的,只怪太菜了。
    also24
        7
    also24  
       2021-04-18 17:01:26 +08:00
    @ZiShuo
    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 这个数组看起来好像没用
    ZiShuo
        8
    ZiShuo  
    OP
       2021-04-18 17:33:58 +08:00
    @also24 大佬,按你说的方法一步一步搞下去也没搞出来,可耻的问一句能做个伸手党嘛?
    eason1874
        9
    eason1874  
       2021-04-18 19:02:14 +08:00
    连是什么算法都不知道,就别折腾了。

    对称加密用 https://github.com/brix/crypto-js,PHP 解密用 openssl_decrypt

    非对称加密用 https://github.com/travist/jsencrypt,PHP 解密用 openssl_private_decrypt
    siweipancc
        10
    siweipancc  
       2021-04-19 08:58:00 +08:00 via iPhone
    真让人头大……你先搞清楚加密协议
    Wounmay9976
        11
    Wounmay9976  
       2021-04-19 09:18:12 +08:00
    同意 9 楼,如果是为了实现功能建议直接用现有的轮子,比自己写的要好到不知哪儿去。
    ZiShuo
        12
    ZiShuo  
    OP
       2021-04-19 11:26:09 +08:00
    @also24 感觉大佬的指点,已经解码出来了。
    iikebug
        13
    iikebug  
       2021-04-19 11:39:29 +08:00
    搞个 wasm 的,随便一个可逆加密算法像 Aes256 这些,后端一调对应算法的库就可以了,为什么要手动写?不嫌弃麻烦啊?
    also24
        14
    also24  
       2021-04-19 16:26:26 +08:00
    @ZiShuo
    OK,这个算法其实不难 ,多点耐心就好~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2809 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 13:41 · PVG 21:41 · LAX 05:41 · JFK 08:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.