uinapp和php实现RSA + AES 双向通信加密

2023-10-30

使用场景

  • 如果只是为了防止用户数据泄露,有条件用https,那不要犹豫,赶快买个证书。
  • 但是https也有局限性,加密层位于http层(应用层)和tcp层(传输层)之间, 所以抓到的http层的数据并没有加密。

单独加密的弊端

  • 单独用RSA非对称加密的话,客户端解密的时候需要用到私匙,这样无异于裸奔,使得整个加密毫无意义,除非你客户端只加密不解密,服务器直接返回明文,但这样就不是双向加密了
  • 单独用AES对称加密的话,加密解密用同一个密匙,密匙就在客户端放着,也是裸奔

AES + RSA 加密思路

  • 在启动APP时,本地随机生成AES密匙,不做持久化存储。

  • 通信的时候,将AES密匙通过RSA加密发送给服务器,将通信内容用过AES加密发送给服务器,这样服务器通过RSA解密得到AES密匙,再通过AES解密得到通信明文内容。

  • 返回数据的时候,服务器通过AES加密返回密文,客户端用过AES解密得到明文。这样,抓包是无法获取AES密匙的,AES密匙只存在于本地内存中

  • 总结来说,就是通过AES加密通信内容,RSA加密AES密匙

以下为简单实现过程,在实际线上项目请对公钥进行缓存,ASE私钥定期更新处理,以保证性能和安全两不误!

uinapp片段
创建文件test.vue,内容如下:

<template>
	<view>
		<button type="warn" @click="test()" plain>测试</button>
		<text v-show="res!==null">返回结果:{{res}}</text>
	</view>
</template>

<script>
	import CryptoJS from '@/js_sdk/encryption/crypto-js/crypto-js';
	import JSEncrypt from '@/js_sdk/encryption/jsencrypt/jsencrypt';
	export default {
		data() {
			return {
				publicKey: null, // RSA加密公匙
				aesKey: null, // AES加密密匙
				iv: 'YM_CHAT_TOOLS_MS', //
				aesEncryptKey: null, // AES加密密匙的RSA加密字符串	
				res: null,
			}
		},
		mounted() {
			this.initEncryption();
		},
		methods: {
			test() {
				let params = {
					id: 123,
					name: '我爱我家呀~'
				};
				uni.request({
					url: 'http://im.xxx.cn/test.php', //仅为示例,并非真实接口地址。
					data: this.EncrypRequestParams(params),
					success: (res) => {
						this.res = this.DecryptResData(res.data);
						console.log('this.res:' + this.res);
					}
				});
			},
			DecryptResData(res) //解密返回结果
			{
				return this.decrypt(res, this.aesKey, this.iv);
			},
			EncrypRequestParams(params = {}) //加密请求参数
			{
				if (this.publicKey === null) {
					uni.showToast({
						title: "请先获取公钥",
						duration: 2000,
						mask: true
					})
					return;
				}
				params.timestamp = this.getTimestamp();
				params = this.encrypt(JSON.stringify(params), this.aesKey, this.iv);
				params = {
					params: params,
					aesEncryptKey: this.aesEncryptKey,
				};
				console.log('params:' + JSON.stringify(params));
				return params;
			},
			//初始化通讯密钥
			initEncryption() {
				uni.request({
					url: 'http://im.xxx.cn/public.key', //仅为示例,并非真实接口地址。
					success: (res) => {
						this.publicKey = res.data;
						this.aesKey = this.initAesKey();
						this.aesEncryptKey = this.rsaEncrypt(JSON.stringify(this.aesKey), this.publicKey);

						console.log('this.publicKey:' + this.publicKey);
						console.log('this.aesKey:' + this.aesKey);
						console.log('this.aesEncryptKey:' + this.aesEncryptKey);
						console.log('初始化成功');
					}
				});
			},
			getTimestamp() //获取10位时间戳
			{
				let tmp = Date.parse(new Date()).toString();
				tmp = tmp.substr(0, 10);
				return tmp;
			},
			// 加密函数
			encrypt(str, KEY, IV = '') {
				var key = CryptoJS.enc.Utf8.parse(KEY);
				var iv = CryptoJS.enc.Utf8.parse(IV);
				var encrypted = CryptoJS.AES.encrypt(str, key, {
					iv: iv,
					mode: CryptoJS.mode.CBC,
					padding: CryptoJS.pad.Pkcs7
				});
				return encrypted.toString();
			},

			//解密
			decrypt(str, KEY, IV = '') {
				var key = CryptoJS.enc.Utf8.parse(KEY);
				var iv = CryptoJS.enc.Utf8.parse(IV);
				var decrypt = CryptoJS.AES.decrypt(str, key, {
					iv: iv,
					mode: CryptoJS.mode.CBC,
					padding: CryptoJS.pad.Pkcs7
				});
				return decrypt.toString(CryptoJS.enc.Utf8);
			},

			//公钥加密
			rsaEncrypt(word, publicKey) {
				const encrypt = new JSEncrypt();
				encrypt.setPublicKey(publicKey);
				return encrypt.encrypt(word);
			},

			//生成随机aes秘钥
			initAesKey() {
				return CryptoJS.MD5(new Date().getTime() + this.randomString(32)).toString();
			},

			//生成随机字串符
			randomString(len) {
				len = len || 32;
				var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
				var maxPos = $chars.length;
				var pwd = '';
				for (let i = 0; i < len; i++) {
					pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
				}
				return pwd;
			},

		}
	}
</script>

php片段
创建test.php,内容如下

<?php
$iv = 'YM_CHAT_TOOLS_MS';
//公钥
$public_key = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu8oSJJAAF4+t4JPoP+LV
3qZTp32K/8tCWGfR/+HE4YwVap63pADKfTkJhBtdaVJK++4DZTxp4zmAbNpV9cNt
eAizRcGb1ytyZp+dLjpW3jBE9DarE5xKBkNCFkf2pF5mfE6inlG2lBSYa0MNt8ZY
s7nPmu+qNYlIeshfm8OuEmNuJVRUNHY7jPgEjZq9Z5Q+kA0MJ7P097PSWfR1FJ12
WufsDH93JK4D7C4iACPoU2l1NywVmOGnjtqdjYfZSlu1kpPKAy0USdEDVxwMWR/v
WbK6Jk7rJWvpR7IY/jLWSTSdwPBA/HT/exdU+YT7BwEy2vzD4Ik/fLSj1LEaNyiK
AQIDAQAB
-----END PUBLIC KEY-----';
//私钥解密
$private_key = '-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7yhIkkAAXj63g
k+g/4tXeplOnfYr/y0JYZ9H/4cThjBVqnrekAMp9OQmEG11pUkr77gNlPGnjOYBs
2lX1w214CLNFwZvXK3Jmn50uOlbeMET0NqsTnEoGQ0IWR/akXmZ8TqKeUbaUFJhr
Qw23xlizuc+a76o1iUh6yF+bw64SY24lVFQ0djuM+ASNmr1nlD6QDQwns/T3s9JZ
9HUUnXZa5+wMf3ckrgPsLiIAI+hTaXU3LBWY4aeO2p2Nh9lKW7WSk8oDLRRJ0QNX
HAxZH+9ZsromTusla+lHshj+MtZJNJ3A8ED8dP97F1T5hPsHATLa/MPgiT98tKPU
sRo3KIoBAgMBAAECggEAEBp/+8qtd1fG3V9Rp0jYdkNlIRPO+6h+g/5DL+I4c+8D
VyVNMi8vLhXaDw4ZsJJyA7ChcekAW4/ux2bhwDWGCakVVoIHzyfWo55EaFZwZJVX
FGoruX7JikfyPt7k86t0tmw33cO8GG67s1cIsh28NY1VlD/BJN4k7QKJ0F2za7gd
ekjIDOmLC3AV8LPwsej9ZBgtZS6q7qo8+JRdHu+qPP2lNlEbInIRCiqjrs8Ymqjn
mq+pjFjTeIb5nYaRJzloiny9/6BsV10tj14KHeakq8azY8zOnP4UhGLbqpSCTzuo
7VDxd/lP8KsRwy9A75fY8mmHX1VtXpXy9jf4Dpx7AQKBgQDeMGoXEk6gSxVhi0dN
KOVe/ux4SCoAjRRmJmaMzOAfscBv17wEr74AamBwiXH2vrZpXgcqaa4t7nNi2pbG
8ZM6G+kBapf9NYTOw4VyLZgYyAflkDrtM/rd4pE8guKOBTtv3EDiCUJw24NjjPh8
+nqwXl+BnYzMbDXry/v6bnyZeQKBgQDYXZStekUgOS3TQgM0NvQkwYXRCFmqMqHO
1DMXUkWTTj0RQK75T1krlPMku/04vlseolVf+m9t51ox7iaEsNq2r3UCs/w4bsj5
hE0a/iBo8+e5sB/oXF16ywKc035XCTaTVnqWHeOqaSSvuh9YYn29PIwM1f2Cu8zQ
n84qO/vayQKBgBPJI+liC/ZiOUkyaesJFUPcV5pucq8R4RsnmEI5jEvGPGi5QVj5
fWX0ExpyYt+iJARGB0VTm9sjPMs0w/B7Wqz2B03E/DvkJCt1ZdDBFqY+SdW7fkPZ
OSHBJ0XIMfyLortXVb/LK0t5gL3As/ANLhe+j6qvKPabPEH/LDUk2ZuhAoGBANEY
hwGrwzgj6hRanEwOu5z15QOhJT4lFliSnBlyqch0+PE+aJqJQ2yp0txyTIJU/Cw7
x3QsyxkUVwcf1tuvKn8YS2VkWWCUN+djIzzt0JZ8+DlsazmcYb60iH7UqSklvzde
gLOoiQd7+zdUEMzSyh9ibxpMh2WbZpFLjusj8v55AoGBAI0dsu0ZW/WGvHYNwpn8
XP8x9N0/RoNyrwd+UnXQg4Kn5jw5NsEyhcfR9h/nl4kpDbnw1OY+TpfzIUABOVwf
VKWZ9VQjNGWxuKrqBSY7ViM8QkHvOVIo4aRRf5ITlmErs3fAh6islj8DJR1HHqFz
xHm/4gaL5CuAB22ljEPUgxir
-----END PRIVATE KEY-----';


$aesEncryptKey = $_GET['aesEncryptKey'];
$content = $_GET['params'];
$return_de = openssl_private_decrypt(base64_decode($aesEncryptKey), $decrypted, $private_key);
if (!$return_de) {
    return ('解密失败,请检查RSA秘钥');
}
$decrypted = json_decode($decrypted, true);

$de = openssl_decrypt($content, 'AES-256-CBC', $decrypted, 4, $iv);

$content = [
    "data" => [
        'time' => date("Y-m-d H:i:s"),
    ],
    "msg"  => 'OK',
    "code" => 200,
];
$res_en = base64_encode(openssl_encrypt(json_encode($content), "AES-256-CBC", $decrypted, 1, $iv));
echo $res_en;

说明
参数iv事先确认好前后端一致即可,注意是16进制
crypto-js和jsencrypt包下载
在线生成RSA秘钥,推荐长度2048bit,私钥不填即可

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

uinapp和php实现RSA + AES 双向通信加密 的相关文章

随机推荐

  • Android平台GB28181设备接入技术探讨

    GB T28181技术背景 在此之前 我们先对协议规范做个简单了解 GB28181协议是一种用于视频监控系统互联互通的国际标准 它定义了视频监控系统中的设备间如何进行通信 交换数据和协调控制 以下是GB28181协议的一些主要内容 设备互联
  • 期货中的正向交易与反向交易

    期货中的正向交易和反向交易 两者之间有什么样的共同点又存在什么样的差异 本文转发自公众号 反跟单交易 转载需注明出处 首先有一点值得认同 两者都属于交易 大家都抱有同样的赢利目的 就好像我们要去北京一样 虽然大家的出发点不同 乘坐的交通工具
  • Word处理控件Aspose.Words功能演示:在 Python 中将 Word DOCX 或 DOC 转换为 PDF

    Word 到PDF是最流行和执行最广泛的文档转换之一 DOCX或DOC文件在打印或共享之前会转换为 PDF 格式 在本文中 我们将在 Python 中自动将 Word 转换为 PDF 步骤和代码示例将演示如何使用 Python 将 Word
  • 公司自建机房IDC还是选择云服务器?以腾讯云为例

    大企业是选择自购服务器自建机房还是使用腾讯云服务器 都说企业上云是趋势 自建机房是一次性支出 上云租赁云服务器等产品需要年年续费 大型企业有必要把数据中心迁移上云吗 腾讯云服务器网想说 自建机房购买服务器等硬件并不是一次性支出 后续人工成本
  • 如何确定一个期刊是不是EI?

    去爱思唯尔官网下载最新的目录 网址 https www elsevier com solutions engineering village content compendex 打开EXCEL查看 SERIALS就是罗列出的所有的EI期刊和
  • 应急响应基础(三)——Windows日志分析

    Windows日志分析 一 Windows事件日志简介 1 Windows事件日志 Windows系统日志是记录系统中硬件 软件和系统问题的信息 同时还可以监视系统中发生的事件 用户可以通过它来检查错误发生的原因 或者寻找受到攻击时攻击者留
  • 拒绝“割韭菜”— 谈谈区块链正经的商用场景!

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 作者 林喜东 腾讯云高级工程师 最近区块链有多火 已经无需过多阐述 无论你是主动了解 还是被比特币 加密猫 3点钟无眠区块链等刷屏 相信区块链概念已经在多数人心中萌芽 但区块链这么火
  • ndvi计算公式_NDVI时间序列分析原理与实现(CV和Sen+MK趋势分析)

    NDVI时间序列分析原理与实现 CV和Sen MK趋势分析 总结两种常用的NDVI时间序列栅格分析方法 变异系数和Sen MK趋势分析 简单介绍原理和实现代码 实验数据均为年际变化数据 在CV中使用的是多波段ENVI数据 Sen MK趋势分
  • 《从Paxos到ZooKeeper》读书笔记之第一章(一)

    从Paxos到ZooKeeper 读书笔记之第一章 一 开始读 从Paxos到ZooKeeper 这本书 以了解和使用ZooKeeper 这里会记录一些随笔画下来的自以为的重点 自己理解和代码块 第一章 分布式结构 1 1 从集中式到分布式
  • springboot 启动后,调用接口时报错404问题汇总(层层推进、超全面)

    确保项目启动成功 看到这条日志才能判定项目是启动成功的 确保controller类被成功注册到了springboot容器中 首先 按springboot的类扫描规则来说 启动类和被扫描的组件类应该要在同一包下的 验证策略 从springbo
  • 联调QuartersII + ModelSim(下载安装)

    目录 1 ModelSim安装 1 之前埋得坑 2 如果额外装完整版的ModelSim 我还是推荐按照这个博客的步骤就好 安装文件我已经在上一篇博客一起给大家了 3 存在的问题 一定要管理员模式使用软件 2 联调QuartersII Mod
  • Mysql(数据库基础篇)

    棒棒有言 也许我一直照着别人的方向飞 可是这次 我想要用我的方式飞翔一次 人生 既要淡 又要有味 凡事不必太在意 一切随缘 缘深多聚聚 缘浅随它去 凡事看淡点看开些 顺其自然 无意于得 就无所谓失 人生 看轻看淡多少 痛苦就远离你多少 本章
  • MATLAB&机器学习进阶

    本文借鉴了数学建模清风老师的课件与思路 可以点击查看链接查看清风老师视频讲解 清风数学建模 https www bilibili com video BV1DW411s7wi 目录 一 K最近邻 KNN 二 决策树 三 支持向量机 四 集成
  • 喜欢就争取,得到就珍惜,错过就忘记—dbGet(二)

    通过前面一篇对dbGet基本用法的介绍 大家应该对它有一定了解了吧 那接来下 我们就要学习一下进阶的dbGet用法了 dbGet是由它基本的语法加上各种object的attribute的组合构成的 大家在熟悉基本语法之后 就应该去学习各个o
  • OpenThread is an Open Source Implementation of Thread IoT Networking Protocol

    本文转载至 http www cnx software com 2016 05 12 openthread is an open source implementation of thread iot networking protocol
  • zabbix邮件报警配置

    前言 Zabbix监控服务端 客户端都已经部署完成 被监控主机已经添加 Zabiix监控运行正常 在Zabbix服务端设置邮件报警 当被监控主机宕机或者达到触发器预设值时 会自动发送报警邮件到指定邮箱 邮件服务可以使用系统自带的邮件服务来发
  • linuxrpm命令卸载python_Linux RPM包安装、卸载、升级命令讲解

    一个 RPM 包包含了已压缩的软件文件集以及该软件的内容信息 通常表现为以 rpm 扩展名结尾的文件 例如 samba rpm 如果需要对RPM包进行操作则需要使用rpm命令 一 RPM包的来源 所有RPM包都在系统光盘的Packages目
  • coco数据集80个分类是哪些_目标分类定位,实时速度检测...目标检测5大挑战与解决方案...

    图像分类是指计算机根据图像内容对图像进行分类或分配标签 通常只需利用预先训练好的神经网络 对最后几个吞吐量层进行微调 然后就可以看到很好的结果 然而 仅在几年前 对图像中的单个目标进行分类和查找未知数量是极其困难的 现在 这项被称为目标检测
  • HTML 标签

    定义和用法 声明必须是 HTML 文档的第一行 位于 标签之前 声明不是 HTML 标签 它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令 在 HTML 4 01 中 声明引用 DTD 因为 HTML 4 01 基于
  • uinapp和php实现RSA + AES 双向通信加密

    使用场景 如果只是为了防止用户数据泄露 有条件用https 那不要犹豫 赶快买个证书 但是https也有局限性 加密层位于http层 应用层 和tcp层 传输层 之间 所以抓到的http层的数据并没有加密 单独加密的弊端 单独用RSA非对称