java登陆页实现前端RSA加密,后端RSA解密

前后端登录的密码加密和解密 salt 盐,每一个用户在注册的时候随机生成一个盐,在做用户明文登录,转换成二次加密,然后根据用户的盐在进行一次加密保存到数据库,这样即使数据库被袭击,用需要大量时间来破解密码。在一个典型的前后端应用中,前端对密码进行加密后传给后端,后端再进行解密或验证。这通常涉及前端加密、后端解密或验证的相互配合。后端收到加密后的密码后,不进行解密,而是对密码进行相同的加密(使用相同的哈希函数或加密算法和密钥),然后与数据库中存储的加密后密码进行比对。前端可以使用各种加密库或算法对密码进行加密。 阅读详情

实现思路

由RSA随机生成一对公钥和私钥,公钥方到客户端,私钥放到服务端,发送数据的时候由公钥对传输数据进行加密,然后发送给服务端,服务端用私钥才能对数据进行解密.下面是代码实现的例子

前端

jsencrypt.js
保存到项目中,并引入,提交明文密码之前,调用此方法加密

// 加密
function getSignString(data) {
    var encrypt = new JSEncrypt();
    // 公匙,由后端返回到前台
    var pubKey = parent.publicKey;
    encrypt.setPublicKey(pubKey);
    var encodePassword = encrypt.encrypt(data);
    return encodePassword;
}

后台传输公钥(此处前后端不分离,采用thymeleaf渲染)

  <script th:inline="javascript">
        parent.publicKey = [[${#servletContext.getAttribute('publicKey')}]];
    </script>

后端

从配置文件读取预先准备好的公钥,存入servlet上下文中

package com.test.framework.startup;

import com.test.common.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;

import javax.servlet.ServletContext;

/** 系统启动往 servlet 上下文塞入数据
 * ClassName AppStartup
 * Description
 *
 * @author wang
 * Date 2021/3/22 11:28
 */
@Order(1)
@Component
public class AppStartup implements ApplicationRunner, ServletContextAware {

    private static final Logger log = LoggerFactory.getLogger(AppStartup.class);

    @Value("${test.kkFileUrl}")
    private String kkFileUrl;

    @Value("${test.ip}")
    private String ip;

    @Value("${server.port}")
    private String port;

    @Value("${rsa.public.key}")
    private String publicKey;

    private ServletContext servletContext;

    @Override
    public void run(ApplicationArguments args) {
        log.info("initialization ...");
        servletContext.setAttribute(Constants.KK_FILE_URL, kkFileUrl);
        servletContext.setAttribute(Constants.SERVER_URL, ip + ":" + port);
        servletContext.setAttribute(Constants.PUBLIC_KEY, publicKey);
        log.info("OK, completed");
    }


    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
}

工具类

package com.test.common.utils;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * 实现的思路:
 * 由RSA随机生成一对公钥和私钥,公钥方到客户端,私钥放到服务端,
 * 发送数据的时候由公钥对传输数据进行加密,然后发送给服务端,服务端用私钥才能对数据进行解密.下面是代码实现的例子
 *
 * ClassName RSAUtils
 * Description
 *
 * @author wang
 * Date 2021/7/7 10:41
 */
public class RSAUtils {


    private static Logger logger = LoggerFactory.getLogger(RSAUtils.class);


    /**
     * 用于封装随机产生的公钥与私钥
     * @param
     * @return
     */
    private static Map<Integer, String> keyMap = new HashMap<>();


    /**
     * 测试方法
     *
     * @param args
     * @return void
     * <p>
     * <p>
     * 前端用crypto-js进行加密,
     * npm i jsencrypt,
     * 然后页面头引入import JSEncrypt from 'jsencrypt';
     * const encrypt = new JSEncrypt();
     * encrypt.setPublicKey('你的公钥');
     * password = encrypt.encrypt(‘你的密码’);// 加密后的字符串
     */
    public static void main(String[] args) {
        //生成公钥和私钥
        genKeyPair();
        //加密字符串
        String message = "df723820";
        System.out.println("随机生成的公钥为:" + keyMap.get(0));
        System.out.println("随机生成的私钥为:" + keyMap.get(1));
        String messageEn = encrypt(message, keyMap.get(0));
        System.out.println("加密后的字符串为:" + messageEn);
        String messageDe = decrypt(messageEn, keyMap.get(1));
        System.out.println("还原后的字符串为:" + messageDe);
    }

    /**
     * 随机生成密钥对
     *
     * @param
     * @return void
     */
    public static void genKeyPair() {
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = null;
        try {
            keyPairGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }
        // 初始化密钥对生成器,密钥大小为96-1024位
        assert keyPairGen != null;
        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
        keyMap.put(0, publicKeyString);  //0表示公钥
        keyMap.put(1, privateKeyString);  //1表示私钥
    }

    /**
     * RSA公钥加密
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return 密文
     */
    public static String encrypt(String str, String publicKey) {
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = null;
        String outStr = null;
        try {
            pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
        } catch (InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }
        //RSA加密
        return outStr;
    }

    /**
     * RSA私钥解密
     *
     * @param str        加密字符串
     * @param privateKey 私钥
     * @return 铭文
     */
    public static String decrypt(String str, String privateKey) {
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = null;
        //RSA解密
        Cipher cipher = null;
        String outStr = null;
        try {
            priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            outStr = new String(cipher.doFinal(inputByte));
        } catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }
        return outStr;
    }


}

登陆控制器

package com.test.project.security.system.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.test.common.utils.RSAUtils;
import com.test.common.utils.ServletUtils;
import com.test.common.utils.StringUtils;
import com.test.common.utils.security.ShiroUtils;
import com.test.framework.web.controller.BaseController;
import com.test.framework.web.domain.AjaxResult;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 登录验证
 *
 * @author test
 */
@Controller
public class LoginController extends BaseController
{

    @Value("${rsa.private.key}")
    private String privateKey;

    @PostMapping("/login")
    @ResponseBody
    public AjaxResult ajaxLogin(HttpSession session, String username, String password, Boolean rememberMe)
    {
    	// 使用秘钥将前端加密密码解密
        password = RSAUtils.decrypt(password, privateKey);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
        Subject subject = SecurityUtils.getSubject();
        try
        {
            subject.login(token);
            session.setAttribute("user", JSONObject.toJSONString(ShiroUtils.getSysUser()));
            return AjaxResult.success("操作成功", token);
        }
        catch (AuthenticationException e)
        {
            String msg = "用户或密码错误";
            if (StringUtils.isNotEmpty(e.getMessage()))
            {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }


}

参考链接:添加链接描述
 
参考链接:添加链接描述

SpringBoot+VUE登录加密解密 【代码】SpringBoot+VUE登录加密解密。 阅读详情

相关推荐

JAVA-WEB项目中,前后台结合AES和RSA对数据加密处理

java web中使用AES和RSA加密数据

u011998957的博客 1万+

前端AES加密,后端解密,有效防止数据外泄

/AES加密 var key = "ABCDEFGHIJKL_key";

hexianfan的博客 1万+

vue+SpringBoot项目前后端数据加解密,实现登录密码前端加密,后端来解密

有个需求就是登录时,前端需要将用户输入的密码进行加密后作为参数传递给后端,后端进行解密。 1.前端方面:Vue 先安装crypto-js npm install crypto-js 如果失败了就用cnpm安装吧 cnpm install crypto-js 前端在src文件夹下的utils文件夹下新建一个Secret.js文件,其代码如下: import CryptoJS from 'crypto-js' // 默认的 KEY 与 iv 如果没有给 const KEY = CryptoJS.enc.U

qq_37635012的博客 1450

java 前端加密后端解密_前端登陆加密和后端解密

实现了前端对数据进行加密后传输,后端对加密的数据进行解密,然后去数据库对比。因为要解密所以采用对称加密算法。不讨论哪个对称加密算法好,这里采用DES,在实现的过程中发现要找一个js版本的DES加密,并且java能DES解密的还真不容易。加解密思路由于是对称加密,所以加解密的密钥就非常重要。这里采用uuid作为加解密的密钥,而且每次请求页面时生成的uuid都不一样,保证每次的密钥都不知道是什么。看后...

weixin_28731231的博客 3245

前后端AES加密与C#解密实战指南

高级加密标准(AES)是对称加密算法之一,广泛应用于现代数据安全领域。它由美国国家标准与技术研究院(NIST)于2001年选定,并在全球范围内推广。AES支持三种不同长度的密钥:128位、192位和256位,其中128位密钥是目前使用最为广泛的。

weixin_42527589的博客 1774

DDS信号发生器设计避坑指南:从AD9834配置到巴特沃斯滤波实战

本文详细解析了基于AD9834芯片的DDS信号发生器设计中的关键技术要点与常见陷阱,涵盖时钟源选择、寄存器配置时序、巴特沃斯滤波器设计等核心内容。针对中高频段信号质量优化,提供了实用的解决方案和代码示例,帮助工程师规避设计误区,提升信号发生器的性能和稳定性。

2y3u4i5o6p的博客 786

使用非对称加密(RSA) 实现前端加密后端解密

数据加密方式有: 单向加密、对称加密、非对称加密、加密盐、散列函数、数字签名。

joe0235的博客 4273

VisionMaster位置修正功能深度解析:如何让找圆工具自动跟随移动目标?

本文深度解析海康威视VisionMaster平台的位置修正功能,重点介绍如何通过模板匹配与找圆工具的智能联动实现移动目标的动态追踪。文章详细阐述了工业视觉检测中的坐标系同步原理、模板匹配配置技巧及异常处理策略,为工程师提供了一套完整的工业级解决方案。

uu89012的博客 287

前端对用户名密码加密处理,后端解密

js资源地址链接:https://pan.baidu.com/s/1kfQZ1SzP6DUz50D–g_ziQ。后端使用php获取数据。

sang521jia的博客 1907

分数计算器(C++课设)

需求概述 (1)设计一个分数计算器,进行分数的算术运算和逻辑运算。 (2)能够像使用基本数据的对象一样,对分数进行“+”、“-”、“*”和“/”等算术运算和比较两个分数的大小。 (3)以a/b的形式输入输出分数,允许输入输出整数这种特殊形式。 (4)对不是约化型的分数进行约化,避免分母为负数。 (5)如果分数的分母为0、除数为0或输入时格式有错,采用异常处理机制解决。 输入 以分数的形式输入。(如1/2) 若分母为0会抛出异常,重新输入。 菜单页面 RationalNumber.h(头文件) #ifnd

sadnessss的博客 8770

雷光联动自动化标校方法

动态标校需要利用动目标,在雷达和光电同时看到目标时记录光电的方位、俯仰,以及利用雷达给的目标信息计算的方位俯仰,手动记录两者的数值,多方位,多距离段记录,费时费力,且人工记录数据不全,计算容易出差错,耗费成本和精力太大。目标相距设备的水平距离 = acos(cos(设备纬度弧度值) * cos(目标纬度弧度值) * cos(设备经度弧度值 – 目标经度弧度值) + sin(设备纬度弧度值) * sin(目标纬度弧度值)) * 6378137;本发明涉及光电技术领域,安防领域,尤其涉及雷达光电动态标校等。

u013358093的博客 1580

前端js jsencrypt加密,后端解密

前端引入jsencrypt.min.js。

CYY941027的博客 1万+

基于PINN的一个简单的求解偏微分方程实例

本人是做化工模拟的一名学生,最近在学习PINN(Physics-Informed Neural Networks,物理信息神经网络)对管道动力学进行建模研究,PINN由于其对机理与数据的良好兼顾性非常热门,本文是作者对PINN入门研究过程的一个练手小题目,main code也是作者代码是基于pytorch2.6.0写的,发上来供各位参考,欢迎研究管道动力学和PINN的小伙伴一起讨论~

weixin_64491760的博客 1743

RSA之前端加密后端解密

RSA加密解密方式有:(1)公钥加密,私钥解密;(2)私钥加密,公钥解密;此文章中以下我使用的是;

weixin_42949219的博客 2471

从 0 到 1 构建 Graph RAG 系统:本地图谱 + 通义千问落地实践

本文介绍了一个基于知识图谱的检索增强生成系统(Graph RAG),该系统结合领域知识图谱、语义检索和大模型问答,旨在提供结构化、精准的技术问答服务。文章详细说明了项目背景、目标、核心技术架构以及实现方法,包括本地图谱构建、Neo4j数据库接入、语义检索和大模型集成等关键环节。该系统支持混合检索、多轮问答和知识图谱关联理解,能够有效减少大模型幻觉,提升问答的准确性和可解释性。文中还展示了核心代码结构和流程图,呈现了从文档加载到图谱构建再到问答生成的完整流程。该系统适用于需要处理复杂领域知识的研发和数据分析场

m0_58378112的博客 1403

NX二次开发点通过云配准获取相同体

先找到体的参考方向(这个参考方向对于相同体重合之后是相同的),这个时候我们的思路是三个不共线的点确定一个坐标系,然后和绝对方向求转换矩阵。然后获取体的所有边的几何中心,把这些点通过转换矩阵转换之后存起来,再和另外一个体转换之后的点数据作对比,在误差范围内配对点的数量等于体获取点的数量就是相同体

qq_39541524的博客 1650

vue前端RSA加密java后端解密的方法

最近安全测试的总是测出安全漏洞来,让开发改。想了想干脆把请求参数都加密下,前端加密后端解密,这样总差不多了。看了下AES加密,是对称的,前后端用这个不太行。于是想到用RSA加密,是非对称的,可以前端加密后端解密。

BHSZZY的博客 5940

华为OD机试:查找接口成功率最优时间段 (C/C++/Py/Java/JS/GO)

华为OD机试双机位C卷 查找接口成功率最优时间段,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。

qq_45776114的博客 4687

【碎片知识点】RSA加密,前端公钥加密,后端私钥解密

写这篇文章之前,搞掂这几行代码,付出了3天时间研究网上的文章全部都看了一遍,无数次AI写代码(AI写的基本上是全错的)踩坑无数,才得以总结出最实用的RSA加密与解密的使用踩的最大坑就是:前端拿到公钥加密得到的密文,给后端私钥解密,发现出现各种错误。开始正题,内容很短前端:Vue框架(JavaScript)后端:sprintboot(Java)工具类:hutool(就这一个够了)

weixin_46301214的博客 2876

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

前端加密,后端解密的过程及代码(密码明文传输解决,不是太保险。key在前端有显示)

解决明文传输,AES前端加密后端解密

weixin_44538241的博客 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

若依ruoyi前端vue使用jsencrypt.js加密后端java进行RSA解密(前后端交互RSA加解密)

一般用来加密,大家都可以获取得到,私钥用来解密,当然你也可以混着用,以下示例是前端通过加密,后端解密.

洗刷先生的博客 5570

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

用户密码的加密解密操作(前端加密,后端解密)

用户密码的加密解密操作 作者是个小菜狗,行文过程基本都基于自己理解,没有深入查阅文献,如有错误,还请大神指出 背景: 公司做的是一个某某平台的系统,包括前台和后台,作者刚毕业,刚开始试用,带我的师傅让我实现密码的加密解密,说实话,都有封装好的api,直接调用什么的,真的没啥难度,后来被其他小事情耽搁了,回过头来,前辈已经做好了,就叫我好好看看,理解下,嗯嗯……说好的让我做的,咋就自己弄了呢?嘿嘿 1、流程 先说说加密的需要,http协议默认情况下是以明文进行传输的,即没有对网上传输的数据进行加密的,

weixin_42510217的博客 2万+

使用RSA实现前端公钥加密后端私钥解密

SpringBoot实现用户登录的前端解密后端解密 RSA前端加密后端解密避免出现明文密码传递 话不多说,直接开撸 前端JS 项目中先添加rsa.js文件 链接:https://pan.baidu.com/s/1r9930MkS4n8TR9IsOIXV-Q 提取码:hd52 添加完成之后在项目中引入rsa.js <script src="js/rsa.js"></script> <!--根据自己的文件路径添加即可--> 使用Vue,element ui实现 va

胡迪警长的博客 3283

java前后端加密解密crypto-js

适用于接口数据敏感信息,比如 明文传输姓名、居住地址、手机号等信息,如果存在明文传输敏感数据问题、数据泄漏风险,即可使用此方法加密解密解决。

myyw001的博客 1万+

前端加密,后端解密(用RSA和AES256双重加密)

7、服务器端收到key_str用RSA2048私钥解密key_str得到AES256密钥,然后用AES256密钥解密sec_text获得请求数据。4、前端发请求的时候random一个AES256的key,然后用RSA2048公钥加密Key生成key_str。5、前端发的请求体用AES256key整个加密生成sec_text。6、前端发请求的时候将key_str放入请求头(或者请求体也可以)3、后端RSA2048私钥写到配置文件中。2、前端写死RSA2048公钥。

weixin_45644355的博客 2822

前后端加密传输,采用RSA算法

【代码】前后端加密传输,采用RSA算法。

qq_22266389的博客 330
上一篇: springboot整合redis解决订单重复请求的问题
下一篇: springboot在工具类中使用 @Value
宁漂打工仔
博客等级 码龄9年 1万+粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁漂打工仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值