加密解密同时满足前端和后端使用

编程知识 更新时间:2023-04-03 21:09:57

我们需要第前端传输内容进行加密然后传递到后端,我们该如何做呢?

偶然间看到网络上有一个加密解密代码,然后我开始进入郁闷的道路,这些代码有时好有时又行了,

问题在哪里呢? 我研究了很久,终于修复了错误,并讲加密解密代码分享给大家。

首先上代码,以下代码同网络上类似的代码有区别,请特别注意。

JS 相关

"use strict"
import md5 from 'js-md5'
import { encode, decode } from 'js-base64';
export default {
	//加密
	encode(txt, key){
		var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/-=";
		var nh = 1;//Math.floor(Math.random() * 64) ;//获取一个字符 
		var ch = chars[nh];//字典中字符
		var mdKey = md5(key + ch);//创建了一个随机的key
		mdKey = mdKey.substr(nh % 8, nh % 8 + 7);
		txt = encode(txt);//base64
		txt = txt.replace('=','');//替换多余的等号等号是为了凑字数没有实际意义
		var tmp = '',j = 0, k = 0;
		for (var i = 0; i < txt.length; i++) {
			k = k == mdKey.length ? 0 : k;//获取mdKey中的索引
			//57(随机位置)+ (base64字符在字典中的位置) + (字典中字符码) 
			j = (nh + chars.indexOf(txt[i]) + mdKey[k++].charCodeAt(0)) % 64;//余数
			tmp += chars[j];
		}
		return encodeURIComponent(ch + tmp);//
	},
	//解密
	decode(txt, key){
		txt = decodeURIComponent(txt);
		var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/-=";
		var ch = txt[0];
		var nh = chars.indexOf(ch);
		var mdKey = md5(key + ch);
		mdKey = mdKey.substr(nh % 8, nh % 8 + 7);
		txt = txt.substr(1);
		var tmp = '', j = 0, k = 0;
		for (var i = 0; i < txt.length; i++) {
			k = k == mdKey.length ? 0 : k;
			j = chars.indexOf(txt[i]) - nh - mdKey[k++].charCodeAt(0);
			while (j < 0) {
				j += 64;
			}
			tmp += chars[j];
		}
		return decode(tmp);
	}
};

PHP相关代码

<?php
//php加密解密:同时满足前端加密解密要求
class Encryption{
	//解密函数
	 public static function decode($txt, $key = '******')
	 {
	  $txt = urldecode($txt);
	  $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/-=";
		 $ch = $txt[0];
		 $nh = strpos($chars,$ch);
		 $mdKey = md5($key.$ch);
		 $mdKey = substr($mdKey,$nh%8, $nh%8+7);
		 $txt = substr($txt,1);
		 $tmp = '';
		 $i=0;$j=0; $k = 0;
		 for ($i=0; $i<strlen($txt); $i++) {
			$k = $k == strlen($mdKey) ? 0 : $k;
			$j = strpos($chars,$txt[$i])-$nh - ord($mdKey[$k++]);
			while ($j<0) $j+=64;
			$tmp .= $chars[$j];
		 }
		 return base64_decode($tmp);

	 }
	 //加密函数
	 public static function encrypt($txt, $key = '******')
	 {
	  $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/-=";
	  $nh = rand(0,64);
	  $ch = $chars[$nh];
	  $mdKey = md5($key.$ch);
	  $mdKey = substr($mdKey,$nh%8, $nh%8+7);
	  $txt = base64_encode($txt);  #如果没有4个字节的整数倍末尾用等号补上
	  $txt = str_replace('=','',$txt);//替换没有用的等号否则解密会出错的
	  $tmp='';$i=0;$j=0;$k = 0;
	  for ($i=0; $i<strlen($txt); $i++) {
	   $k = $k == strlen($mdKey) ? 0 : $k;
	   $j = ($nh+strpos($chars,$txt[$i])+ord($mdKey[$k++]))%64;
	   $tmp .= $chars[$j];
	  }
	  return urlencode($ch.$tmp);
	 }
}

以上内容大部分来自网络,但是我调试了很久,基本上看是类似但是都无法成功加密和解密。

其中问题在于 base64 函数和 encodeURIComponent 相关函数带来的困扰。

网络上的代码错误的原因:

1、没有考虑base64 在加密后的对4字节通过“=” 号补齐的规定,但是部分内容加密后无法解密。

2、没有考虑到网络传输中转码的要求,而在前端(JS) 采用了  encodeURI 和 decodeURI,导致后端(PHP) 断无法解密

为此以上代码已经做了修正:

js 端修正

txt = encode(txt);//base64
        txt = txt.replace('=','');//替换多余的等号等号是为了凑字数没有实际意义

PHP端修正

$txt = str_replace('=','',$txt);//替换没有用的等号否则解密会出错的

对应前端加密应用场景,例如密码加密,保证传输过程是加密状态;

当然以上前端代码如何直接使用肯定是有问题的,建议看我的rollup打包开箱就用文章,直接将该内容打包成js类库文件;这样就相对好些

感谢本加密解密的最初作者。

感谢阅读本文的作者。

如果需要技术交流留言联系。

更多推荐

加密解密同时满足前端和后端使用

本文发布于:2023-04-03 21:09:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/19d305205f7afd51dc6d989d6d9e74c7.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:后端   加密解密

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!

  • 39958文章数
  • 14阅读数
  • 0评论数