RSA非对称加密

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;

  }

}

如此可以实现密码、账号的加密:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值