最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot + Vue 基于 RSA 的用戶身份認證加密機制實現(xiàn)過程

 更新時間:2024年11月23日 09:57:44   作者:徐州蔡徐坤  
RSA是一種非對稱加密算法,適用于用戶身份認證加密,本文介紹了基于RSA的用戶身份認證加密機制的實現(xiàn),包括前端Vue.js使用jsencrypt庫對用戶名密碼進行加密,后端使用RSA私鑰解密驗證用戶憑據(jù),感興趣的朋友跟隨小編一起看看吧

Spring Boot + Vue 基于 RSA 的用戶身份認證加密機制實現(xiàn)

什么是RSA?

RSA算法是一種非對稱加密算法,與對稱加密算法不同的是,RSA算法有兩個不同的密鑰,一個是公鑰,一個是私鑰

RSA公開密鑰密碼體制是一種使用不同的加密密鑰與解密密鑰,“由已知加密密鑰推導(dǎo)出解密密鑰在計算上是不可行的”密碼體制

在公開密鑰密碼體制中,加密密鑰(即公開密鑰)PK是公開信息,而解密密鑰(即秘密密鑰)SK是需要保密的。加密算法E和解密算法D也都是公開的。雖然解密密鑰SK是由公開密鑰PK決定的,但卻不能根據(jù)PK計算出SK

正是基于這種理論,1978年出現(xiàn)了著名的RSA算法,它通常是先生成一對RSA密鑰,其中之一是保密密鑰,由用戶保存;另一個為公開密鑰,可對外公開,甚至可在網(wǎng)絡(luò)服務(wù)器中注冊。為提高保密強度,RSA密鑰至少為500位長。這就使加密的計算量很大。為減少計算量,在傳送信息時,常采用傳統(tǒng)加密方法與公開密鑰加密方法相結(jié)合的方式,即信息采用改進的DES或IDEA對話密鑰加密,然后使用RSA密鑰加密對話密鑰和信息摘要。對方收到信息后,用不同的密鑰解密并可核對信息摘要

安全需求介紹

背景:在安全掃描過程中,系統(tǒng)被檢測到存在中危漏洞,影響了用戶登錄環(huán)節(jié)的信息安全性

漏洞描述

Web程序在處理用戶登錄過程中,針對用戶名和口令在傳輸前未采用加密。用戶名和口令一旦被惡意攻擊者嗅探或暴力破解得到后,可以直接利用它去登錄系統(tǒng)。

解決方案:建議對用戶名、口令等參數(shù)值采用強加密算法,如SHA512、RSA、AES、國密算法等,避免使用MD5、Base64、DES、3DES等弱算法。

問題分析:未加密的敏感信息在傳輸過程中易被攔截,尤其是在公共網(wǎng)絡(luò)環(huán)境下。這使得系統(tǒng)的認證機制成為攻擊目標,存在較高的安全隱患

需求實現(xiàn)

  • 在前端使用安全加密算法對用戶名和密碼進行加密,防止信息裸露傳輸
  • 后端解密用戶信息并進行驗證,同時保障傳輸數(shù)據(jù)的完整性與安全性

前后端交互流程

基于RSA加密的登錄流程,Web端和服務(wù)端的交互過程詳細步驟:

  1. 用戶發(fā)起登錄請求
  • 用戶在Web端輸入登錄操作,Web端開始處理登錄流程
  • Web端向服務(wù)端發(fā)送一個請求,要求獲取RSA加密所需的公鑰
  1. 服務(wù)端返回公鑰
  • 服務(wù)端接收到公鑰請求后,從系統(tǒng)中讀取公鑰信息,并將公鑰發(fā)送回Web端。這個步驟的響應(yīng)無需校驗
  1. Web端加密用戶憑據(jù)
  • Web端使用獲取到的公鑰,對用戶的用戶名和密碼進行加密。加密后的數(shù)據(jù)用于安全傳輸,避免敏感信息在網(wǎng)絡(luò)中被截獲
  • Web端將加密后的用戶名和密碼通過HTTPS協(xié)議發(fā)送給服務(wù)端。HTTPS協(xié)議提供了額外的安全層,防止中間人攻擊
  1. 服務(wù)端解密并驗證
  • 服務(wù)端接收到加密的數(shù)據(jù)后,使用私鑰對加密內(nèi)容進行解密。私鑰是嚴格保密的,只在服務(wù)端保存和使用服務(wù)端對解密后的用戶名和密碼進行驗證,檢查憑據(jù)是否正確并符合登錄要求
  1. 返回登錄結(jié)果
  • 服務(wù)端驗證完成后,將登錄驗證的結(jié)果返回給Web端。結(jié)果可以是登錄成功或失敗的信息
  1. Web端處理響應(yīng)
  • Web端接收并處理服務(wù)端返回的登錄結(jié)果,并顯示相應(yīng)的提示或進行后續(xù)操作

前端使用 RSA 加密密碼

在前端 Vue.js 中,使用 jsencrypt 庫對用戶名密碼進行加密,并將加密后的用戶名密碼發(fā)送給后端

安裝 jsencrypt庫

在Vue.js 項目中運行以下命令來安裝 jsencrypt

npm install jsencrypt --save

實現(xiàn)敏感信息加密

在 Vue.js 登錄頁面中,對敏感信息進行加密,然后發(fā)送給后端:

// 引入 jsencrypt 和 Base64 編碼庫
import JSEncrypt from 'jsencrypt';
// 需要安裝 js-base64 庫
import { Base64 } from 'js-base64'; 
export default {
  data() {
    return {
      username: '', // 用戶輸入的用戶名
      password: ''  // 用戶輸入的密碼
    };
  },
  methods: {
    /**
     * 使用 RSA 公鑰加密字符串
     * @param {string} str - 需要加密的字符串
     * @returns {string|null} - 加密后的字符串,若失敗返回 null
     */
    encryptString(str) {
      // 初始化 JSEncrypt
      const encrypt = new JSEncrypt();
      // 設(shè)置公鑰
      const publicKey = `
        -----BEGIN PUBLIC KEY-----
        ...公鑰內(nèi)容...
        -----END PUBLIC KEY-----
      `;
      encrypt.setPublicKey(publicKey);
      // 加密字符串并返回加密結(jié)果
      return encrypt.encrypt(str);
    },
    /**
     * 用戶登錄邏輯
     */
    login() {
      // 獲取用戶輸入的用戶名和密碼
      const username = this.username.trim(); // 去除多余空格
      const password = this.password.trim();
      // 驗證用戶名和密碼是否為空
      if (!username || !password) {
        this.$message.error('用戶名或密碼不能為空'); // 提示用戶
        return;
      }
      // 加密用戶名和密碼
      const encryptedUsername = this.encryptString(username);
      const encryptedPassword = this.encryptString(password);
      // 驗證加密是否成功
      if (!encryptedUsername || !encryptedPassword) {
        this.$message.error('加密失敗,請檢查公鑰配置');
        return;
      }
      // Base64 編碼的主要作用是將加密后的數(shù)據(jù)轉(zhuǎn)換成由可見 ASCII 字符組成的字符串,以便在網(wǎng)絡(luò)傳輸或存儲時避免因特殊字符引發(fā)的兼容性問題
      const base64EncodedUsername = Base64.encode(encryptedUsername);
      const base64EncodedPassword = Base64.encode(encryptedPassword);
      // 發(fā)送登錄請求到后端
      this.$axios.post('/api/login', {
        username: base64EncodedUsername, // 加密后的用戶名
        password: base64EncodedPassword  // 加密后的密碼
      }).then(response => {
        // 登錄成功后的處理邏輯
        if (response.data.success) {
          this.$message.success('登錄成功');
          // 跳轉(zhuǎn)到主頁面或其他邏輯
        } else {
          this.$message.error(response.data.message || '登錄失敗');
        }
      }).catch(error => {
        // 請求失敗的處理邏輯
        console.error('登錄請求失敗:', error);
        this.$message.error('登錄失敗,請稍后重試');
      });
    }
  }
};

服務(wù)器端生成RSA的公私鑰文件

Windows環(huán)境 生成rsa的公私鑰文件

安裝 OpenSSL:下載并安裝 OpenSSL for Windows,可以從 OpenSSL 官網(wǎng) 下載適合的版本。

image-20241120105453452

生成 RSA 私鑰

  • 在安裝目錄的bin目錄下面,打開命令提示符(cmd
  • 運行以下命令生成一個2048位的私鑰文件 private_key.pem
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

  1. 生成 RSA 公鑰
  • 使用生成的私鑰來提取公鑰,運行以下命令:
openssl rsa -pubout -in private_key.pem -out public_key.pem

?

Linux環(huán)境 生成rsa的公私鑰文件

使用RSA算法生成pem格式的私鑰文件,指定密鑰長度2048

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

使用RSA算法在上述私鑰文件基礎(chǔ)上生成pem格式的公鑰文件

openssl rsa -pubout -in private_key.pem -out public_key.pem

執(zhí)行完成后,會看到輸出兩份文件 private_key.pem, public_key.pem。

后端代碼實現(xiàn)

返回給前端的公鑰接口

將生成的兩份密鑰文件放入指定的目錄中,然后在配置文件中配置公私鑰文件所屬路徑

 /**
     * 獲取公鑰
     */
    @GetMapping("/getPublicKey")
    public AjaxResult getPublicKey() {
        // 加載資源
        File file = new File("公鑰的文件所屬路徑");
        if (!file.exists()) {
            throw new BusinessException("未獲取到指定公鑰文件");
        }
        String publicKey;
        try (InputStream inputStream = Files.newInputStream(file.toPath())) {
            publicKey = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
        } catch (IOException e) {
            log.error("讀取公鑰文件失敗", e);
            // 返回錯誤信息
            return AjaxResultGenerator.error("讀取公鑰文件失敗");
        }
        // 檢查 publicKey 是否為 null 或空字符串
        if (publicKey == null || publicKey.isEmpty()) {
            return AjaxResultGenerator.error("公鑰內(nèi)容為空");
        }
        // 刪除PEM格式的頭部和尾部以及所有空格、換行符
        publicKey = publicKey.replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "")
                .replaceAll("\\s+", "");
        return AjaxResultGenerator.success(publicKey);
    }

解密前端傳入的加密字符串

前端的賬戶和密碼進行rsa加密并且base64編碼后,調(diào)用正常登錄接口login(),readPrivateKeyAndDecode()方法將 RSA 加密并 Base64 編碼的字符串解碼后,再用 RSA 私鑰對解碼后的數(shù)據(jù)進行解密,最終返回解密后的原始數(shù)據(jù)

pom.xml

<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-all</artifactId>
	<version>5.8.26</version>
</dependency>

登錄和解密方法

 /**
     * 用戶名密碼登錄
     *
     * @param loginBody 登錄信息
     * @return 結(jié)果
     */
    @PostMapping("/v1/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        // 使用 RSA 私鑰解密
        String username = readPrivateKeyAndDecode(loginBody.getUsername());
        String password = readPrivateKeyAndDecode(loginBody.getPassword());
        loginBody.setUsername(username);
        loginBody.setPassword(password);
 	    // 執(zhí)行正常的登錄邏輯...
        return AjaxResultGenerator.success();
    }
    /**
     * 讀取私鑰并解密
     *
     * @param rsaEncoded64Str 已rsa加密并且base64編碼后的字符串
     * @return
     */
    public String readPrivateKeyAndDecode(String rsaEncoded64Str) {
        // 加載資源
        File file= new File("私鑰的文件所屬路徑");
        if (!file.exists()) {
            throw new BusinessException("未獲取到指定私鑰文件");
        }
        String privateKey;
        try (InputStream inputStream = Files.newInputStream(file.toPath())) {
            privateKey = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
        } catch (IOException e) {
            log.error("讀取私鑰文件失敗", e);
            throw new BusinessException("讀取私鑰文件失?。? + e.getMessage());
        }
        if (StringUtils.isBlank(privateKey)) {
            throw new BusinessException("私鑰內(nèi)容為空");
        }
        // 刪除PEM格式的頭部和尾部以及所有空格、換行符
        privateKey = privateKey.replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s+", "");
        // 進行base64解密
        String decodedUsername = new String(Base64.getDecoder().decode(rsaEncoded64Str));
        // 使用 RSA 私鑰解密,用到了hutool-all中的類
        return new RSA(privateKey, null)
                .decryptStr(decodedUsername, KeyType.PrivateKey);
    }

實現(xiàn)效果

到此這篇關(guān)于Spring Boot + Vue 基于 RSA 的用戶身份認證加密機制實現(xiàn)的文章就介紹到這了,更多相關(guān)Spring Boot Vue 身份認證加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring配置中transactionAttributes的使用方法介紹

    Spring配置中transactionAttributes的使用方法介紹

    這篇文章主要介紹了Spring配置中transactionAttributes的使用方法介紹的相關(guān)內(nèi)容,具有一定參考價值,需要的朋友可以了解下。
    2017-09-09
  • 解決nacos報錯java.lang.ClassNotFoundException: com.netflix.config.DynamicPropertyFactory的問題

    解決nacos報錯java.lang.ClassNotFoundException: com.netflix.

    這篇文章主要介紹了解決nacos報錯java.lang.ClassNotFoundException: com.netflix.config.DynamicPropertyFactory的問題,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • SpringBoot項目中新增脫敏功能的實例代碼

    SpringBoot項目中新增脫敏功能的實例代碼

    項目中,由于使用端有兩個,對于兩個端的數(shù)據(jù)權(quán)限并不一樣。Web端可以查看所有數(shù)據(jù),小程序端只能查看脫敏后的數(shù)據(jù),這篇文章主要介紹了SpringBoot項目中新增脫敏功能,需要的朋友可以參考下
    2022-11-11
  • Eclipse導(dǎo)出安卓apk文件的圖文教程

    Eclipse導(dǎo)出安卓apk文件的圖文教程

    這篇文章主要為大家詳細介紹了Eclipse導(dǎo)出安卓apk文件的圖文教程,以圖文結(jié)合的方式為大家分享了Eclipse是如何導(dǎo)出安卓apk文件的步驟,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Spring和Mybatis整合的原理詳解

    Spring和Mybatis整合的原理詳解

    這篇文章主要介紹了Spring和Mybatis整合的原理詳解,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • Spring Bean的線程安全問題

    Spring Bean的線程安全問題

    Spring容器中的Bean是否線程安全,本文主要介紹了Spring Bean的線程安全問題,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 9種Java單例模式詳解(推薦)

    9種Java單例模式詳解(推薦)

    這篇文章主要介紹了9種Java單例模式詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • JAVA獲取Image的三種方式

    JAVA獲取Image的三種方式

    這篇文章主要介紹了JAVA獲取Image的三種方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java檢測網(wǎng)絡(luò)是否正常通訊

    Java檢測網(wǎng)絡(luò)是否正常通訊

    在網(wǎng)絡(luò)應(yīng)用程序中,檢測IP地址和端口是否通常是必要的,本文主要介紹了Java檢測網(wǎng)絡(luò)是否正常通訊,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • java string類的常用方法詳細介紹

    java string類的常用方法詳細介紹

    在開發(fā)過程中經(jīng)常會使用到j(luò)ava string類的方法,本文將以此問題進行詳細介紹
    2012-11-11

最新評論

天全县| 清流县| 汉川市| 吉安县| 来宾市| 三原县| 墨竹工卡县| 额济纳旗| 中宁县| 秦安县| 临澧县| 峨眉山市| 荣成市| 伊宁县| 洛宁县| 长顺县| 闵行区| 自贡市| 彭山县| 嘉黎县| 两当县| 甘孜县| 武隆县| 株洲县| 阳西县| 宁乡县| 丽江市| 左贡县| 贞丰县| 隆安县| 集贤县| 射洪县| 噶尔县| 禄丰县| 称多县| 永靖县| 景东| 大厂| 临桂县| 廉江市| 舞钢市|