RSA非对称加密
一、非对称加密的概念
非对称加密(Asymmetric Encryption)指的是:**一对公钥(public key)和私钥(private key)**来进行加解密。
- 公钥 公开,用于加密数据;
- 私钥 保密,用于解密数据;
- 数据经过公钥加密后,只有对应的私钥才能解密。
常见算法有 RSA 、ECC 等。
适用场景:
- 安全传输对称加密的密钥(比如 AES 的密钥)
- 数字签名(保证数据来源和完整性)
二、加密实现的流程
1、后端生成 RSA 公钥/ 私钥,私钥保存在服务器,公钥暴露给前端。
2、获取公钥,用它加密敏感数据(如密码)。
3、发送密文到后端。
4、用私钥解密得到明文,再进行业务逻辑处理。
如图:

三、实战
这里用vue+ spring boot 实现登录的场景做例子:
(注意:有些用到了JWT令牌)
作者博客文章:JWT令牌-CSDN博客
Spring boot:
新建rsa工具类:
private static KeyPair keyPair;
// 生成RSA密钥对
static {
try {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
//设置密钥长度
generator.initialize(2048);
//生成密钥对
keyPair = generator.generateKeyPair();
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取公钥
public static PublicKey getPublicKey() {
return keyPair.getPublic();
}
// 获取私钥
public static PrivateKey getPrivateKey() {
return keyPair.getPrivate();
}
创建公钥返回接口:
@RestController
@RequestMapping("/rsa")
public class RsaController {
// 获取公钥
@GetMapping("/publicKey")
public String getPublicKey() {
return Base64.getEncoder().encodeToString(RsaUtil.getPublicKey().getEncoded());
}
}
创建登录控制类:
@Data
static class EncryptedRequestRsa {
private String username;
private String password;
}
//登录
@PostMapping("/user/login")
public Result login(@RequestBody EncryptedRequestRsa request) throws Exception {
// 1. 使用私钥解密前端传来的用户名和密码
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, RsaUtil.getPrivateKey());
// 解密用户名
byte[] usernameBytes = cipher.doFinal(Base64.getDecoder().decode(request.getUsername()));
String username = new String(usernameBytes, StandardCharsets.UTF_8);
// 解密密码
byte[] passwordBytes = cipher.doFinal(Base64.getDecoder().decode(request.getPassword()));
String password = new String(passwordBytes, StandardCharsets.UTF_8);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_name", username);
User one = userService.getOne(queryWrapper);
if (one == null) {
return Result.error("503","用户不存在");
}
// 验证密码(数据库里存的是加盐 hash)
if (!ADDSalt.checkPassword(password, one.getPassword())) {
return Result.error("504","密码错误");
}
// 2. 生成 token
String token = jwtUtil.generateToken(username);
// 3. 封装返回数据
HashMap<Object, Object> result = new HashMap<>();
result.put("token", token);
return Result.success(result);
}
Vue前端:
创建工具类:
// utils/rsa.js
import JSEncrypt from "jsencrypt";
class rsaUtil {
constructor() {
this.encryptor = new JSEncrypt();
}
// 设置公钥
setPublicKey(publicKey) {
this.encryptor.setPublicKey(
"-----BEGIN PUBLIC KEY-----\n" + publicKey + "\n-----END PUBLIC KEY-----"
);
}
// 加密
encryptRsa(data) {
return this.encryptor.encrypt(data);
}
}
export default new rsaUtil();
在请求中调用:
const onFinish = async (values) => {
loading.value = true
try {
// 1. 获取后端公钥
const { data: publicKey } = await request.get("/rsa/publicKey");
rsaUtil.setPublicKey(publicKey);
// 2. 分别加密用户名和密码
const encryptedUsername = rsaUtil.encryptRsa(values.username);
const encryptedPwd = rsaUtil.encryptRsa(values.password);
if (isLogin.value) {
// 3. 登录请求
const response = await request.post('/user/login', {
username: encryptedUsername,
password: encryptedPwd
});
localStorage.setItem("token", response.data.data.token);
alert("登录成功");
router.push({ path: '/ai' });
} else {
// 3. 注册请求
const response = await request.post('/user/register', {
username: encryptedUsername,
password: encryptedPwd
});
console.log('注册:', values);
alert("注册成功");
isLogin.value = true;
}
} catch (error) {
console.error(error);
alert("操作失败");
} finally {
loading.value = false;
}
}
如此可以实现密码、账号的加密:

