当前位置: 首页> 科技> 名企 > 绍兴网站建设方案书_开发一个小程序流程_中国域名注册局官网_山东做网站

绍兴网站建设方案书_开发一个小程序流程_中国域名注册局官网_山东做网站

时间:2025/7/28 17:08:22来源:https://blog.csdn.net/redarmy_chen/article/details/147061396 浏览次数:2次
绍兴网站建设方案书_开发一个小程序流程_中国域名注册局官网_山东做网站

在当今的互联网应用开发中,用户数据的安全性至关重要。登录功能作为用户进入系统的第一道防线,其安全性更是不容忽视。本文将介绍一种基于 RSA 加密的登录方案,前端使用 Node.js 的 node-forge 库对密码进行公钥加密,后端使用 Spring Boot 的 RSUtils 工具类进行私钥解密,从而确保用户密码在传输过程中的安全性。

一、RSA 加密原理简介

RSA 是一种非对称加密算法,它使用一对密钥:公钥和私钥。公钥用于加密数据,私钥用于解密数据。在登录场景中,前端使用公钥对用户密码进行加密,然后将加密后的密码发送到后端。后端使用私钥对加密的密码进行解密,从而获取原始密码,再进行后续的验证操作。

二、前端实现:使用 Node.js 的 node-forge 加密密码

(一)引入 node-forge 库

在前端项目中,首先需要引入 node-forge 库。可以通过 npm 安装:

bash复制

npm install node-forge

然后在代码中引入:

JavaScript复制

import forge from 'node-forge';

(二)获取公钥

前端登录界面

<template><div class="about"><el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"><el-form-item label="活动名称" prop="name"><el-input v-model="ruleForm.name"/></el-form-item><el-form-item label="密码" prop="password"><el-input v-model="ruleForm.password" show-password/></el-form-item><el-form-item><el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button><el-button @click="resetForm('ruleForm')">重置</el-button></el-form-item></el-form></div>
</template>

公钥需要从后端获取。后端可以通过某种方式(如 API)将公钥发送到前端。前端将公钥存储起来,以便后续使用。

<script>
//导入node-forge
import forge from 'node-forge'
import JSEncrypt from 'jsencrypt';export default {data() {return {publicKey: '',ruleForm: {name: 'chj',password: 'gb123456'}};},created() {this.initPublicKey();},methods: {initPublicKey() {this.axios.get('http://localhost:9999/api/getrsa').then(res => {this.publicKey = res.data.publicKey;console.log(this.publicKey);});}}}
</script>

(三)使用公钥加密密码

当用户输入密码并点击登录按钮时,前端使用存储的公钥对密码进行加密,将加密后的密码作为登录请求的一部分发送到后端

  submitForm(formName) {//获取publicKeyObj对象var publicKeyObj = forge.pki.publicKeyFromPem(this.publicKey);console.log("原始数据",this.ruleForm.password);//对URI组件统一编码var encode = encodeURIComponent(this.ruleForm.password);console.log("编码后数据",encode)//对字符串加密处理var encrypted = publicKeyObj.encrypt(encode, 'RSA-OAEP', {md: forge.md.sha256.create(),mgf1:{md: forge.md.sha1.create()}});console.log("加密后数据",encrypted);//工具类转码var encryptedBase64 = forge.util.encode64(encrypted);console.log("base64后得编码",encryptedBase64);//发送请求携带加密的串this.axios.post('http://localhost:9999/api/login', {name: this.ruleForm.name,password: encryptedBase64}).then(res => {console.log(res);});},resetForm(formName) {this.$refs[formName].resetFields();}

三、后端实现:Spring Boot 结合 RSUtils 工具类解密密码

工具类RSUtils

package org.example.util;import com.sun.crypto.provider.SunJCE;import java.nio.charset.StandardCharsets;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.io.ByteArrayOutputStream;
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import java.security.*;
import java.util.*;public class RSAUtils {public static final String KEY_ALGORITHM = "RSA";private static final int MAX_DECRYPT_BLOCK = 256;//Base64解码private static final Base64.Decoder decoder64 = Base64.getDecoder();//Base64编码private static final Base64.Encoder encoder64 = Base64.getEncoder();/*** 生成公私钥** @param keySize 密钥长度(如2048)* @return 密钥对* @throws NoSuchAlgorithmException*/public static SecretKey generateSecretKey(int keySize) throws NoSuchAlgorithmException {SunJCE provider=new com.sun.crypto.provider.SunJCE();Security.addProvider(provider);KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");keyGen.initialize(keySize, new SecureRandom());KeyPair pair = keyGen.generateKeyPair();PrivateKey privateKey = pair.getPrivate();PublicKey publicKey = pair.getPublic();return new SecretKey(encoder64.encodeToString(publicKey.getEncoded()), encoder64.encodeToString(privateKey.getEncoded()));}/*** 私钥解密*/public static String decryptByPrivateKey(String str, String key) throws Exception {Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-1"), PSource.PSpecified.DEFAULT);PrivateKey privateKey = strToPrivateKey(key);cipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParams);byte[] data = decryptBASE64(str);byte[] bytes = dataSegment(data, cipher, MAX_DECRYPT_BLOCK);return new String(bytes, StandardCharsets.UTF_8);}/*** 对数据进行分段加密或解密*/private static byte[] dataSegment(byte[] data, Cipher cipher, int maxBlock) throws Exception{byte[] toByteArray;int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;int i = 0;byte[] cache;// 对数据分段加密解密while (inputLen - offSet > 0) {int var = inputLen - offSet > maxBlock ? maxBlock : inputLen - offSet;cache = cipher.doFinal(data, offSet, var);out.write(cache, 0, cache.length);i++;offSet = i * maxBlock;}toByteArray = out.toByteArray();out.close();return toByteArray;}/*** 获取私钥*/private static PrivateKey strToPrivateKey(String str) throws Exception {PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(decryptBASE64(str));KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);return privateKey;}/*** 字符串转字节数组*/private static byte[] decryptBASE64(String str) {return Base64.getDecoder().decode(str);}public static class SecretKey {private String publicKey;private String privateKey;public SecretKey(String publicKey, String privateKey) {this.publicKey = publicKey;this.privateKey = privateKey;}public String getPublicKey() {return publicKey;}public String getPrivateKey() {return privateKey;}@Overridepublic String toString() {return "SecretKey{" +"publicKey='" + publicKey + '\'' +", privateKey='" + privateKey + '\'' +'}';}}}

后端控制器类代码:

package org.example.controller;import org.example.model.Users;
import org.example.util.RSAUtils;
import org.example.util.RSAtils;
import org.springframework.web.bind.annotation.*;import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;import static java.util.regex.Pattern.compile;@CrossOrigin
@RequestMapping("/api")
@RestController
public class RSAController {//密钥对象private RSAUtils.SecretKey secretKey;//通过构造函数创建对象public RSAController() throws NoSuchAlgorithmException {System.out.println("----------------");secretKey = RSAUtils.generateSecretKey(2048);}@GetMapping("/getrsa")public Map<String,Object> getrsa() throws NoSuchAlgorithmException {Map<String,Object> map = new HashMap<>();String temp="-----BEGIN PUBLIC KEY-----\n" + secretKey.getPublicKey() + "\n-----END PUBLIC KEY-----";map.put("publicKey",temp);// map.put("privateKey",secretKey.getPrivateKey());return map;}@PostMapping("/login")public Map<String,Object> login(@RequestBody Users users) throws Exception {//工具类解密String decryptedData = RSAUtils.decryptByPrivateKey(users.getPassword(),secretKey.getPrivateKey());//创建对象Map<String, Object> map = new HashMap<>();//设置解密成功响应的结果map.put("pass", decryptedData);return map;}
}

model实体类

package org.example.model;import java.io.Serializable;public class Users implements Serializable {private String name;private String password;//空的构造函数public Users() {}//构造函数public Users(String name, String password) {this.name = name;this.password = password;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}

四、安全性考虑

  1. 密钥管理:密钥对的生成和存储需要严格管理。公钥可以公开,但私钥必须保密,不能泄露给任何未经授权的人员或系统。

  2. 传输安全:虽然密码在传输过程中被加密,但仍然需要使用 HTTPS 协议来确保整个通信过程的安全性,防止中间人攻击。

  3. 前端安全:前端代码可能会被篡改,因此需要确保前端代码的完整性和安全性。可以通过代码签名等方式来防止恶意代码注入。

五、测试结果

六、总结

本文介绍了一种基于 RSA 加密的登录方案,前端使用 Node.js 的 node-forge 库对密码进行公钥加密,后端使用 Spring Boot 的 RSUtils 工具类进行私钥解密。通过这种方式,可以有效保护用户密码在传输过程中的安全性。在实际应用中,还需要结合其他安全措施,如 HTTPS、密钥管理等,以确保系统的整体安全性。

关键字:绍兴网站建设方案书_开发一个小程序流程_中国域名注册局官网_山东做网站

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: