加密与安全_前后端通过AES-CBC模式安全传输数据

news2024/9/29 7:27:11

文章目录

  • Pre
  • 概述
  • 前端加密是否有意义?
  • 环境准备
  • 加密方法、MODE和PADDING的选择
  • 前端
  • 后端
  • 应用:从传输到解密的全过程
  • 安全性增强
    • 动态生成密钥和初始向量
      • 1. 前端:动态生成密钥和IV
      • 2. 后端:解密动态密钥和IV
  • 结语

在这里插入图片描述


Pre

加密与安全_解密AES加密中的IV和Seed

加密与安全_双向RSA+AES加密及Code实现

加密与安全_常见的分组密码 ECB、CBC、CFB、OFB模式介绍


概述

当我们在前端和后端之间传输敏感信息时,安全性变得越来越重要。今天,我们将一起探索如何在前端加密密码,并在后端安全解密的过程。

使用Vue.js作为前端框架,并通过Java来处理后端解密。


前端加密是否有意义?

前端加密是否真的有意义?其实,这个问题的答案并不绝对。

  • 一方面,前端加密能够一定程度上防止中间人攻击,从而保护用户的隐私。
  • 但另一方面,如果攻击者能够篡改前端代码,前端加密就形同虚设。

因此,前端加密到底值不值得,还是见仁见智。


环境准备

前端使用的是Vue.js,也可以选择纯JS。同时,我们引入crypto-js库。至于后端,Java将担任这次任务的重任。

为了让前端和后端能够顺利交流,我们必须确保前后端使用相同的加密方式、模式(MODE)和填充方式(PADDING)


加密方法、MODE和PADDING的选择

加密方法、MODE和PADDING之间也必须配合得天衣无缝。前后端的这些参数必须一致,才能确保传输的信息能够正确加密和解密。

必须选择前后端都支持的加密方法、模式和填充方式。

https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html

https://cryptojs.gitbook.io/docs/#pbkdf2


以下是\选择的参数:

  • 加密方法: AES(推荐加密方法,参考:FIPS 197)
  • 模式: CBC(默认模式,参考:FIPS 81)
  • 填充方式: Pkcs7(与Java的PKCS5Padding基本等价)

在这里,我们选择AES/CBC/Pkcs7作为加密组合,而Java端则使用AES/CBC/PKCS5Padding。这样一来,我们的前后端就可以在同一个频道上交流了。


前端

需要引入crypto-js库,并设置好密钥(key)和初始向量(iv)。这些设置必须与后端保持一致,才能确保加密与解密的正确性。

// aesutils.js
import CryptoJs from 'crypto-js'

// 把key、iv设置成固定值,前后端的值要一致
let key = CryptoJs.enc.Utf8.parse("xxxxxx");
let iv = CryptoJs.enc.Utf8.parse("yyyyyy");

export function Encrypt(word) {
    let srcs = CryptoJs.enc.Utf8.parse(word);
    var encrypted = CryptoJs.AES.encrypt(srcs, key, {
        iv: iv,
        mode: CryptoJs.mode.CBC,
        padding: CryptoJs.pad.Pkcs7
    });
    return CryptoJs.enc.Base64.stringify(encrypted.ciphertext);
}

在这个加密函数中,我们将原始文本转换为Base64编码后的密文,然后将其发送到后端。如此一来,前端的密码在传输过程中便不会以明文形式暴露。


后端

后端的任务是接收到前端传来的密文,并将其解密为原始的明文密码。这一步同样至关重要,因为后端需要将这些密码存储或用于后续操作。


import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public class AESUtils {

    private static final String key = "xxxxxx";
    private static final String iv = "yyyyyy";

    public static String deocdeStr(String text) {
        try {
            byte[] encrypted = new Base64().decode(text);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding ");
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec ivParameter = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));

            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameter);

            byte[] decrypted = cipher.doFinal(encrypted);
            String originalString = new String(decrypted, StandardCharsets.UTF_8);
            return originalString;
        } catch (Exception e) {
            return e.toString();
        }
    }
}

后端解密的核心步骤与前端加密紧密关联。首先,我们将Base64编码的密文解码为字节数组,然后利用AES/CBC/PKCS5Padding的组合将其解密为原始字符串。


应用:从传输到解密的全过程

在前端,我们使用工具类加密密码,然后通过axios等方法将加密后的密文传输到后端:

import { Encrypt } from "@/utils/aesutils";

Encrypt(this.$data.formData.password);

在后端,接收到加密的密文后,我们调用工具类解密并还原密码,然后将其用于后续的数据库操作:

 
AESUtils.deocdeStr(user.getPassword());

安全性增强

尽管我们使用了固定的密钥和初始向量(IV),但在实际的生产环境中,这种方式的安全性可能还不够强。接下来,我们将进一步提升安全性,探索如何使用动态生成的密钥和初始向量,并研究在生产环境中如何更好地管理这些关键要素。

动态生成密钥和初始向量

使用固定的密钥和IV,虽然简化了前后端的协调工作,但也带来了风险。一旦密钥和IV被泄露,攻击者就可以轻松解密传输的数据。为了解决这个问题,我们可以采取动态生成密钥和IV的方法。

1. 前端:动态生成密钥和IV

在前端,我们可以在每次需要加密时,动态生成密钥和IV。然后,将密钥和IV与加密后的数据一起发送到后端。为了避免密钥和IV直接暴露在网络传输中,我们可以将它们与加密数据一起加密或使用安全的密钥交换算法。

import CryptoJs from 'crypto-js';

// 生成随机密钥和IV
function generateKeyAndIV() {
    let key = CryptoJs.lib.WordArray.random(128 / 8); // 128-bit key
    let iv = CryptoJs.lib.WordArray.random(128 / 8);  // 128-bit IV
    return { key, iv };
}

// 加密函数
export function encryptWithDynamicKey(word) {
    const { key, iv } = generateKeyAndIV();
    let srcs = CryptoJs.enc.Utf8.parse(word);
    let encrypted = CryptoJs.AES.encrypt(srcs, key, {
        iv: iv,
        mode: CryptoJs.mode.CBC,
        padding: CryptoJs.pad.Pkcs7
    });

    // 将密钥和IV与加密后的数据一起编码
    return {
        ciphertext: CryptoJs.enc.Base64.stringify(encrypted.ciphertext),
        key: CryptoJs.enc.Base64.stringify(key),
        iv: CryptoJs.enc.Base64.stringify(iv)
    };
}

generateKeyAndIV函数生成了一个随机的密钥和IV。然后,我们将这些随机生成的密钥和IV与加密后的数据一起编码并发送给后端。

2. 后端:解密动态密钥和IV

在后端接收到加密数据和动态生成的密钥、IV后,我们需要解码并使用它们进行解密操作。

import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public class AESUtils {

    public static String decryptWithDynamicKey(String ciphertext, String keyBase64, String ivBase64) {
        try {
            byte[] encrypted = new Base64().decode(ciphertext);
            byte[] key = new Base64().decode(keyBase64);
            byte[] iv = new Base64().decode(ivBase64);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
            IvParameterSpec ivParameter = new IvParameterSpec(iv);

            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameter);

            byte[] decrypted = cipher.doFinal(encrypted);
            return new String(decrypted, StandardCharsets.UTF_8);
        } catch (Exception e) {
            return e.toString();
        }
    }
}

这个解密函数接受Base64编码的密文、密钥和IV。我们先将它们解码为字节数组,然后使用它们来解密密文,恢复原始数据。


结语

通过动态生成密钥和初始向量,并使用安全的密钥管理服务,我们可以大幅提升系统的安全性。这不仅能防止密钥泄露带来的风险,还能通过安全的密钥交换和管理,确保前后端通信的绝对安全。

在实际的生产环境中,密钥的管理和轮换至关重要,建议使用专业的KMS来简化并加强密钥管理工作。通过这些措施,可以构建一个更加安全和稳健的系统 。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2088117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TMGM:欧元区通胀放缓将支持9月欧洲中央银行降息

八月份德国通胀率出乎意料的下降超过预期。欧洲中央银行可能会保持其放松的货币政策。美元/欧元矫正性下跌可能在本周结束前继续。 欧洲统计局将在周五公布八月份欧元区消费者价格(调和)指数(HICP)的预估数值,预期结果将支持9月份决策者降息的决定。 因为对经济增…

大数据-110 Flink 安装部署 下载解压配置 Standalone模式启动 打包依赖

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

Python 如何进行声音处理(pydub, wave模块)

Python 是一种功能强大的编程语言,它提供了丰富的库和模块用于各种任务的执行,包括声音处理。对于声音处理,pydub 和 wave 模块是最常用的两个库。 一、Python中的声音处理基础知识 在深入探讨具体的模块之前,我们先了解一些声音…

深度学习基础--损失函数

前三章分别介绍了线性回归、浅层神经网络和深度神经网络。这些都属于函数家族,能够实现从输入到输出的映射,其具体的函数取决于模型参数 ϕ \phi ϕ。在训练这些模型时,我们的目标是找到能够为特定任务提供最优输入输出映射的参数。本章将详…

C语言 ——— 文件读取结束的判定

目录 判定文件读取结束的方式 被错误使用的feof函数 判定文件结束的正确使用 判定文件读取结束的方式 判断文本文件是否读取结束: 利用 fgetc 判断返回值是否为 EOF 利用 fgets 判断返回值是否为 NULL 判断二进制文件是否读取结束: 利用 fread 判…

00 Tkinter学习路线

Tkinter学习路线 此Tkinter以更新完毕,几乎涵盖了Tkinter所有知识点 此文章用于快速找到对应的知识点 01 Tkinter介绍 02 Tkinter窗口的管理与设置 03 Tkinter布局方式 04 Tkinter布局组件 05 Tkinter事件 06 Tkinter可变变量 07 Label 组件 08 Button 组件 09 Entr…

大模型技术 | 基于大模型构建本地知识库

前言 随着人工智能技术的发展,大模型已成为智能系统进步的关键力量。 模型以其庞大的数据容量和深度学习能力,为处理复杂任务提供了前所未有的可能性。但在特定应用场景下仍面临挑战,尤其是在需要快速、准确响应的情境中。为了克服这些限制…

.NET Razor类库-热加载 就是运行时编译

1.新建3个项目 1.1 一个.NET Standard2.1项目 IX.Sdk.SvnCICD4NuGet 1.2 一个.NET Razor类库项目 IX.Sdk.SvnCICD4NuGet.RazorWeb 1.3 一个.NET6 Web项目 IX.Sdk.SvnCICD4NuGet.Web 这3个项目的引用关系 Web引用 Razor类库 和 .NET Standard2.1 Razor类库引用.NET Standard2.1…

VBA学习(65):Excel VBA 凭证打印/SQL连接Eexcel文件/Listview控件/CommandButton命令按钮控件

本期内容信息量相当的大,内容涉及很多方面,请耐心阅读,肯定不会让你失望的!建议收藏! Excel中记账凭证的打印,几种思路 Excel表记账的缺点 最新的打印方法:勾选凭证列表,点打印即可…

OpenCV中使用金字塔LK光流法(下)

接下来通过一个demo来调用calcOpticalFlowPyrLK()实现光流计算,需要注意的是该方法适用于具有丰富特征的像素点的光流计算,平坦区域的像素点往往会得到误差较大的结果。所以我们需要先选取得到一些角点,demo中通过goodFeaturesToTrack()这个接口实现角点提取。 如下有两张图…

nvm切换node版本(windows版本)

如果是win系统,不能直接通过npm来安装nvm(npm install nvm不行!)。需要手动去nvm官网下载安装包安装nvm github官网 先卸载本地的node版本 npm ls -g --depth0 // 查看全局安装中是否有早前安装的node 1.点击进去Github上往下滑会发现有一个download。进…

IP网络协议

目录 一、IP协议简介 二、IP协议报头 三、IP网段划分(子网划分) 四、特殊的IP地址 五、IP地址的数量限制 六、私有IP地址和公网IP地址 七、路由 八、分片与组装 一、IP协议简介 IP指网际互连协议,Internet Protocol的缩写&#xff0…

Vue+ElementUI+Electron环境搭建及程序打包

一.环境 Node.js Element-ui Electron 二.Node.js 1.下载并安装Node.js 2.安装完成后,新建目录”node_cache“ ”node_global“ 3.新建及修改环境变量 4.执行如下命令 npm config set prefix "D:\Source_Install\nodejs\node_global" npm config set cache &q…

设计模式-简单工厂模式工厂方法模式

1. 简单工厂模式定义 简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过专门定义一个类来负责创建其他类的实例,这个类通常被称为工厂类。简单工厂模式并不是一种正式的设计模式,但它确实是一种常用的…

认识Kubebuilder

认识Kubebuilder 一、什么是Kubebuilder?Kubebuilder,K8s operator创建框架controller-runtime和controller-tools库 二、Kubebuilder,举例来说开源项目kuik 三、使用 kubebuilder init 创建基础项目四、使用kubebuilder create api生成控制器CachedIma…

gitea仓库迁移新服务器 更新远程仓库地址(git remote remove origin)

文章目录 引言I 镜像部署方式迁移案例迁移容器备份gitea服务器配置II 修改​远程仓库地址set-url语法案例III 扩展基于git命令方式进行代码迁移忽略被追踪的文件(update .gitignore)see also引言 由于部署git仓库的机器不稳定,决定进行服务器迁移。更新远程仓库地址的应用场景…

传统助贷机构如何利用CRM系统转型升级

传统助贷机构在利用CRM系统(客户关系管理系统)进行转型升级时,可以遵循以下几个关键步骤和策略,以优化客户管理、提升业务效率并实现业务增长: 一、明确转型升级目标 首先,传统助贷机构需要明确利用CRM系统…

使用docker compose一键部署 Openldap

使用docker compose一键部署 Openldap LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是一种用于访问分布式目录服务的网络协议,OpenLDAP 是 LDAP 协议的一个开源实现,由 OpenLDAP 项目提供&#x…

python库(21):TextBlob库实现文本处理

1 TextBlob简介 TextBlob 是一个基于 Python 的文本处理库,能够让基础的自然语言处理任务变得异常简单。 它提供了一个简单直观的 API,让你能够轻松执行词性标注、名词短语提取、情感分析、文本分类和关键词提取等功能。 值得一提的是,Tex…

Linux git的基本使用 安装 提交

目录 安装git 首次使用git的配置 拉取仓库 步骤1:新建仓库 步骤2:复制仓库地址 步骤3:远端仓库拉取到本地 上传代码 常用指令 安装git sudo apt-get install git # Ubuntu/Debian sudo dnf install git # Fedora sudo yum insta…