专栏名称: Java基基
一个苦练基本功的 Java 公众号,所以取名 Java 基基
目录
相关文章推荐
独角兽智库  ·  油气开采及服务板块领涨深度投资报告 ·  2 天前  
独角兽智库  ·  某外资解读今日大跌 ·  2 天前  
创伙伴  ·  1.77万亿,最大奶茶IPO来了 ·  昨天  
空空道人早盘必读  ·  先持仓观望 再做决定 ·  2 天前  
空空道人早盘必读  ·  先持仓观望 再做决定 ·  2 天前  
睢宁融媒  ·  最新!他登顶中国首富 ·  3 天前  
51好读  ›  专栏  ›  Java基基

优雅的处理 API 接口敏感数据加解密(方案详解)

Java基基  · 公众号  ·  · 2024-06-28 18:24

正文

👉 这是一个或许对你有用 的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入 芋道快速开发平台 知识星球。 下面是星球提供的部分资料:

👉 这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本

来源:juejin.cn/post/
7358368402795692082


一、背景与目标

随着网络技术的快速发展,数据安全问题日益突出。为了防止爬虫、防请求篡改、防请求重放,以及验证数据完整性,本方案结合HTTPS原理和微信支付加解密设计,通过对称加密、非对称加密、签名等技术,为API接口提供加解密设计和落地。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

二、方案设计

对称加密、非对称加密、哈希算法、验签算法

  • 对称加密: 采用相同的密钥进行加密和解密。具有加密速度快、计算量小的优点,但密钥的安全传输是问题。在本方案中,对称加密主要用于数据的实际加密传输。
  • 非对称加密: 使用一对密钥(公钥和私钥)进行加密和解密。公钥用于加密数据,私钥用于解密数据。非对称加密可以确保密钥的安全传输,但加密速度较慢,不适合长文本加密。在本方案中,非对称加密主要用于对称密钥的加密。
  • 哈希算法: 无论用户输入什么长度的原始数据,经过计算后输出的密文都是固定长度的,只要原数据稍有改变,输出的“摘要”便完全不同
  • 签名算法: 一般指的是,通过私钥对数据进行签名,然后通过公钥对数据进行验签

HTTPS原理概述

HTTPS( Hypertext Transfer Protocol Secure )是一种通过计算机网络进行安全通信的传输协议。它利用SSL/TLS协议在HTTP应用层进行通信加密,通过证书进行身份验证,从而确保数据传输的安全性和完整性。

微信支付加解密原理

  • 请求签名: 通过商户API证书私钥,对每一次请求进行RSA-SHA256签名,微信支付进行验签
  • 回调验签: 微信支付通过平台证书私钥,对每一次回调进行RSA-SHA256签名,商户接收到请求后,通过平台正式公钥进行验签
  • 回调解密: 商户根据配置的apiV3密钥,对加密数据进行AES-256-GCM解密

接口加解密设计思路

  • 密钥交换: 客户端使用服务端的公钥对对称加密的密钥进行加密,然后将密文密钥发送给服务端。服务端使用自己的私钥解密得到对称加密的明文密钥。
  • 数据加密: 客户端使用对称加密的明文密钥对接口数据进行加密,然后发送给服务端。服务端使用相同的对称加密密钥对数据进行解密。
  • 数据哈希(签名): 在数据发送前,客户端计算数据的哈希值,并将哈希值作为数据的一部分发送给服务端。服务端收到数据后,使用相同的算法计算哈希值,并与客户端发送的哈希值进行比较,以验证数据的完整性。
  • 数据有效性校验: 在数据发送前,客户端将当前时间作为数据的一部分发送给服务端。服务端收到数据后,解密得到参数中的时间,并与服务端当前时间进行比较,以验证请求是否过期,防止请求重放。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

三、技术实现

1、密钥生成与管理:

通过工具生成非对称密钥对,服务端负责保管私钥。(客户端也可以定期从服务端获取公钥(传输过程中有泄露的风险),并保存到LocalStorage。)

2、加密算法选择:

对称加密算法可选用常用的AES,非对称加密算法可选用常用的RSA。哈希算法可选用SHA-256、MD5,签名算法可选用RSA-SHA256等。根据Hutool加密算法如下:

// 对称密钥
String key = "key";
AES aes = SecureUtil.aes(key.getBytes());
// 加密
String ciphertext = aes.encryptBase64(content);
// 解密
String result = aes.decryptStr(ciphertext);
// 非对称公钥
String publicKey = "xxxxxxx";
// 对称密钥
String key = "key";
RSA rsa = new RSA(null, publicKey);
// 对对称密钥进行加密
String ciphertextKey = rsa.encryptBase64(key, KeyType.PublicKey);


// 非对称私钥
String privateKey = "xxxxxxx";
RSA rsa2 = new RSA(privateKey, null);
// 对加密的对称密钥进行解密
String key = rsa2.encryptBase64(ciphertextKey, KeyType.PrivateKey);
String data = "测试";
Digester sha256 = new Digester(DigestAlgorithm.SHA256);

System.out.println(sha256.digestHex(data));
// 暂不考虑
String publicKey = "xxxxx";
String privateKey = "xxxxx";
String data = "测试";

Sign privateSign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKey, null);
String sign = new String(Base64.getEncoder().encode(privateSign.sign(data)));
System.out.println("签名:" + sign);

Sign publicSign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, null, publicKey);
System.out.println(publicSign.verify(data.getBytes(), Base64.getDecoder().decode(sign.getBytes())));
3、签名规则:

等queryString和body参数加密后,将queryString、时间戳、明文对称密钥、body参数按顺序进行拼接,然后通过SHA256算法进行哈希得到签名sign,然后将sign放在header中进行传递

4、参数传递:
  • ek(encryt-key): xxxxxxx(非对称加密后的对称密钥)
  • ts: xxxxxxx(时间戳)
  • sign: xxxxxxx

将请求参数 queryString 拼成" param1=value1¶m2=value2 "格式

queryString 进行对称加密,得到" ciphertext=xxxxx ",并重新拼接到url后面

query参数可以参考GET请求

body参数可以通过对称加密得到base64密文,直接用body进行传输

例如:

url?ciphertext=xxxxx
body:xxxxxxxx
5、后端处理:
  1. 请求有效验证: 获取header中ts参数,得到时间戳并判断时间戳是否超过一定时间;
  2. 解密对称密钥: 通过私钥解密header中的ek参数,得到明文的对称密钥key;
  3. 验签: 将queryString、时间戳、明文对称密钥、body参数按顺序进行拼接,然后通过SHA256算法进行哈希得到签名sign,与header中的sign做比较;
  4. 解密参数: 通过明文对称密钥,分别解密queryString、body参数;
  5. 加密响应结果: 请求完成后,将响应结果通过对称加密得到base64密文,并返回给客户端

四、常见问题

Q:为什么需要参考HTTPS来设计接口加解密?

A:HTTPS结合了对称加密和非对称加密,安全性更高,同时也能满足效率要求

Q:如果只使用对称加密有什么问题?

A:客户端是不安全的,很容易暴露密钥,只要一旦暴露,加密就形同虚设

Q:如果只使用非对称加密有什么问题?

A:

  • 非对称加密不支持超长文本加密(RSA只支持117字节);






请到「今天看啥」查看全文


推荐文章
独角兽智库  ·  油气开采及服务板块领涨深度投资报告
2 天前
独角兽智库  ·  某外资解读今日大跌
2 天前
创伙伴  ·  1.77万亿,最大奶茶IPO来了
昨天
空空道人早盘必读  ·  先持仓观望 再做决定
2 天前
空空道人早盘必读  ·  先持仓观望 再做决定
2 天前
睢宁融媒  ·  最新!他登顶中国首富
3 天前
总裁俱乐部  ·  2017年,送您"五个福"!
8 年前
半导体行业联盟  ·  摩尔邀请您与30万读者一起加入
7 年前