网易首页 > 网易号 > 正文 申请入驻

【345期】SpringCloud Gateway API 接口安全设计(加密 、签名)

0
分享至


1 防止数据抓包窃取 1.1 风险简述

简述:当用户登录时,恶意攻击者可以用抓包工具可以拿到用户提交的表单信息,可以获取用户的账号密码,进而可以恶意访问网站。

1.2 RSA 非对称加密 1.2.1 RSA简介

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

1973年,在英国政府通讯总部工作的数学家克利福德·柯克斯(Clifford Cocks)在一个内部文件中提出了一个相同的算法,但他的发现被列入机密,一直到1997年才被发表。对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。

假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。

1983年麻省理工学院在美国为RSA算法申请了专利。这个专利2000年9月21日失效。由于该算法在申请专利前就已经被发表了,在世界上大多数其它地区这个专利权不被承认。

1.2.2 RSA应用过程

非对称算法的在应用的过程如下:

  • 接收方生成公钥和私钥,公钥公开,私钥保留;

  • 发送方将要发送的消息采用公钥加密,得到密文,然后将密文发送给接收方;

  • 接收方收到密文后,用自己的私钥进行解密,获得明文。

1.2.3 RSA工具类package com.demo.utils;

import com.demo.excepiton.RsaException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class RSAUtils {

public static final String PUBLIC_KEY = "public_key";

public static final String PRIVATE_KEY = "private_key";

public static Map generateRasKey() {
Map rs = new HashMap<>();
try {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = null;
keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥 公钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
// 将公钥和私钥保存到Map
rs.put(PUBLIC_KEY, publicKeyString);
rs.put(PRIVATE_KEY, privateKeyString);
} catch (Exception e) {
log.error("RsaUtils invoke genKeyPair failed.", e);
throw new RsaException("RsaUtils invoke genKeyPair failed.");
}
return rs;
}

public static String encrypt(String str, String publicKey) {
try {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
log.error("RsaUtils invoke encrypt failed.", e);
throw new RsaException("RsaUtils invoke encrypt failed.");
}
}

public static String decrypt(String str, String privateKey) {

try {
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
return new String(cipher.doFinal(inputByte));
} catch (Exception e) {
log.error("RsaUtils invoke decrypt failed.", e);
throw new RsaException("RsaUtils invoke decrypt failed.");
}

}

RsaException: 是自定义异常

@Getter
public class RsaException extends RuntimeException {

private final String message;

public RsaException(String message) {
this.message = message;
}

}
1.2.4 UTpackage com.rosh;

import com.alibaba.fastjson.JSONObject;
import com.demo.utils.RSAUtils;
import org.junit.Test;

import java.util.Map;

/**
* @Description:
* @Author: rosh
* @Date: 2021/10/25 22:30
*/
public class RsaTest {

/**
* 用测试生成的公钥,私钥赋值
*/
private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFtTlL61IqIGd+fRLUhJ0MjsqFXFJswCohJ45m51WvbxDPRP3gllW0WChk74D5JEOpMDSWo4C7RfoGlBRNW7kQ6qYGukYZ5jgYpzoT0+gp3on96fQXEyQJysv9xiTPIdmSXXVVj1HAOJw29RbzxIVKUSzzPXvEtXRTtCC1+wkAJQIDAQAB";

private static final String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIW1OUvrUiogZ359EtSEnQyOyoVcUmzAKiEnjmbnVa9vEM9E/eCWVbRYKGTvgPkkQ6kwNJajgLtF+gaUFE1buRDqpga6RhnmOBinOhPT6Cneif3p9BcTJAnKy/3GJM8h2ZJddVWPUcA4nDb1FvPEhUpRLPM9e8S1dFO0ILX7CQAlAgMBAAECgYBC4amtbiKFa/wY61tV7pfYRjzLhKi+OUlZmD3E/4Z+4KGZ7DrJ8qkgMtDR3HO5LAikQrare1HTW2d7juqw32ascu+uDObf4yrYNKin+ZDLUYvIDfLhThPxnZJwQ/trdtfxO3VM//XbwZacmwYbAsYW/3QPUXwwOPAgbC2oth8kqQJBANKLyXcdjZx4cwJVl7xNeC847su8y6bPpcBASsaQloCIPiNBIg1h76dpfEGIQBYWJWbBsxtHe/MhOmz7fNFDS2sCQQCiktYZR0dZNH4eNX329LoRuBiltpr9tf36rVOlKr1GSHkLYEHF2qtyXV2mdrY8ZWpvuo3qm1oSLaqmop2rN9avAkBHk85B+IIUF77BpGeZVJzvMOO9z8lMRHuNCE5jgvQnbinxwkrZUdovh+T+QlvHJnBApslFFOBGn51FP5oHamFRAkEAmwZmPsinkrrpoKjlqz6GyCrC5hKRDWoj/IyXfKKaxpCJTH3HeoIghvfdO8Vr1X/n1Q8SESt+4mLFngznSMQAZQJBAJx07bCFYbA2IocfFV5LTEYTIiUeKdue2NP2yWqZ/+tB5H7jNwQTJmX1mn0W/sZm4+nJM7SjfETpNZhH49+rV6U=";

/**
* 生成公钥私钥
*/
@Test
public void generateRsaKey() {
Map map = RSAUtils.generateRasKey();
System.out.println("随机生成的公钥为:" + map.get(RSAUtils.PUBLIC_KEY));
System.out.println("随机生成的私钥为:" + map.get(RSAUtils.PRIVATE_KEY));

}

/**
* 加密: Yeidauky/iN1/whevov2+ntzXJKAp2AHfESu5ixnDqH5iB7ww+TcfqJpDfkPHfb12Y0sVXw0gBHNJ4inkh7l2/SJBze3pKQU/mg3oyDokTia3JZIs+e80/iJcSfN+yA1JaqY+eJPYiBiOGAF2S6x0ynvJg/Wj0fwp2Tq3PDzRMo=
*/
@Test
public void testEncrypt() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("username", "rosh");
jsonObject.put("password", "123456");
String str = jsonObject.toJSONString();
String encrypt = RSAUtils.encrypt(str, PUBLIC_KEY);
System.out.println(encrypt);
}

@Test
public void testDecrypt() {

String decrypt = RSAUtils.decrypt("Yeidauky/iN1/whevov2+ntzXJKAp2AHfESu5ixnDqH5iB7ww+TcfqJpDfkPHfb12Y0sVXw0gBHNJ4inkh7l2/SJBze3pKQU/mg3oyDokTia3JZIs+e80/iJcSfN+yA1JaqY+eJPYiBiOGAF2S6x0ynvJg/Wj0fwp2Tq3PDzRMo=",
PRIVATE_KEY);

System.out.println(decrypt);
}

}
1.3 案例

SpringCloud Gateway + SpringBoot + Nacos+redis

1.3.1 前端登录代码

后端把公钥跟前端约定好:

html>
登录页面title></p>

head>

登录h1>


账号:
密码:
from>

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
兵者,诡道也?在伊朗“高风险搜救行动”的美版叙事

兵者,诡道也?在伊朗“高风险搜救行动”的美版叙事

澎湃新闻
2026-04-06 14:34:26
世界杯收官最新世界排名:松岛新高!覃予萱飙升11位,向鹏狂跌8位

世界杯收官最新世界排名:松岛新高!覃予萱飙升11位,向鹏狂跌8位

求球不落谛
2026-04-06 06:46:48
第4轮中超“最差”评选:上海海港1人,浙江队2人,津门虎2人

第4轮中超“最差”评选:上海海港1人,浙江队2人,津门虎2人

男足的小球童
2026-04-06 18:24:59
特朗普消失?连续三天未露面引全球猜测,病危还是兵变?真相成谜

特朗普消失?连续三天未露面引全球猜测,病危还是兵变?真相成谜

策略述
2026-04-06 18:12:08
军事 | 拯救大兵,美军炸了还是没炸?谁在说谎?

军事 | 拯救大兵,美军炸了还是没炸?谁在说谎?

新民周刊
2026-04-06 09:09:19
周迅姐姐的自律,全在这碗轻食里了。难怪一直这么瘦,状态绝了!

周迅姐姐的自律,全在这碗轻食里了。难怪一直这么瘦,状态绝了!

小椰的奶奶
2026-04-06 14:29:55
1998年数万华人遭屠杀,中国为何没出兵?26年后答案让人沉默

1998年数万华人遭屠杀,中国为何没出兵?26年后答案让人沉默

哄动一时啊
2026-02-17 22:21:25
突然拉升!美联储、鲍威尔,突发!降息,大消息!

突然拉升!美联储、鲍威尔,突发!降息,大消息!

证券时报e公司
2026-04-04 22:12:45
原来这才是普通家庭存款啊!网友:两套房一辆车,无房贷车贷

原来这才是普通家庭存款啊!网友:两套房一辆车,无房贷车贷

另子维爱读史
2026-03-06 20:12:51
王楚钦夺冠后一举动引发质疑,难怪樊振东、陈梦退出,现在懂了

王楚钦夺冠后一举动引发质疑,难怪樊振东、陈梦退出,现在懂了

林子说事
2026-04-06 18:22:45
所有人都以为大战接近尾声,伊朗突然掀起了开战以来最猛的导弹雨

所有人都以为大战接近尾声,伊朗突然掀起了开战以来最猛的导弹雨

老鹈爱说事
2026-04-07 03:41:25
扣2个日本人质后,伊朗人在日本被铁管打死,小日子飘得有点过了

扣2个日本人质后,伊朗人在日本被铁管打死,小日子飘得有点过了

温读史
2026-04-06 21:06:27
“张雪的机车”,被封禁

“张雪的机车”,被封禁

台州交通广播
2026-04-07 02:04:09
李镇全到底做了什么?让米特里策两次破防拽他头发,还因此被发现

李镇全到底做了什么?让米特里策两次破防拽他头发,还因此被发现

懂个球
2026-04-06 23:54:03
反对派对欧尔班釜底抽薪:上台后修改宪法,欧尔班无法再担任总理

反对派对欧尔班釜底抽薪:上台后修改宪法,欧尔班无法再担任总理

史行途
2026-04-07 03:42:49
张雪与凯越老总私下会面,对方主动祝贺,张雪顺势澄清辞职原因

张雪与凯越老总私下会面,对方主动祝贺,张雪顺势澄清辞职原因

潮鹿逐梦
2026-04-04 23:43:09
阿尔卡拉斯:辛纳赢下阳光双冠后还参加蒙特卡洛让我非常意外

阿尔卡拉斯:辛纳赢下阳光双冠后还参加蒙特卡洛让我非常意外

网球之家
2026-04-06 22:38:01
把情报局当私器、向俄罗斯泄密,一场匈牙利版水门事件如何收场呢

把情报局当私器、向俄罗斯泄密,一场匈牙利版水门事件如何收场呢

环球格局观
2026-04-05 21:57:54
解放军唯一的一次乌龙,一野和二野打了一个晚上,各自伤亡多少人

解放军唯一的一次乌龙,一野和二野打了一个晚上,各自伤亡多少人

旧史新谭
2026-04-05 17:00:22
研究显示:我国男性阴茎疲软状态下的均值是6.5厘米,你达标了吗

研究显示:我国男性阴茎疲软状态下的均值是6.5厘米,你达标了吗

黯泉
2026-04-05 19:00:47
2026-04-07 06:32:49
Java精选
Java精选
一场永远也演不完的戏
1782文章数 3859关注度
往期回顾 全部

科技要闻

折叠屏iPhone要来了,富士康已在试产!

头条要闻

特朗普:7日是最后期限 否则伊朗每座桥梁将被摧毁

头条要闻

特朗普:7日是最后期限 否则伊朗每座桥梁将被摧毁

体育要闻

官方:中国女足球员邵子钦加盟本菲卡

娱乐要闻

唐嫣罗晋新加坡遛娃,6岁女儿身高抢镜

财经要闻

史诗级暴跌"一周年" A股接下来如何走?

汽车要闻

阿维塔06T快上市了 旅行车还能这么玩?

态度原创

艺术
游戏
教育
手机
公开课

艺术要闻

这所小学的校牌竟然全由学生手写,已持续十年

一人开发!国产独立游戏《破晓》4月9日发售

教育要闻

高中坚持阅读外刊,为啥英语成绩没突破词汇没增加,如何上140?

手机要闻

OPPO Find X9s Pro真机现身,还有银色哈苏专业增距镜

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版