前端如何安全存储密钥,防止信息泄露

场景

       把公钥硬编码在前端代码文件里,被公司安全检测到了要整改,于是整理几种常见的前端密钥存储方案。

1. 设置环境变量再读取

        在打包或部署前端应用时,可以将密钥配置为环境变量,在应用运行时通过环境变量读取密钥。这样可以将密钥从源代码中分离出来,避免意外泄露。

a. 前端设置环境变量

        将密钥作为前端应用的环境变量进行配置。但是直接使用环境变量存储密钥也是很危险的,前端代码可以被任何人查看和修改,这意味着敏感信息可能会被泄露。

步骤:

  • 在 .env 文件中设置环境变量

        首先,在项目根目录下的 .env 文件中设置环境变量.

        当然,你也可以设置在特定环境的 .env 文件,如 .env.production、.env.test等,这样可以根据不同的环境设置不同的变量值。

VITE_API_KEY = 'your_api_key_here'
  • 在 Vue 组件中读取环境变量

console.log(import.meta.env.VITE_API_KEY) // 打印 API 密钥

        但是使用这种方法打包后,秘钥仍能在源码中找到。

b. 后端设置环境变量

        将密钥存储在后端环境变量中再由前端读取可以提高安全性,这样密钥不会在客户端暴露。

  • 后端密钥生成与存储:在后端应用中,生成和存储密钥。可以使用安全的密钥生成算法来生成密钥,并将其存储在后端的安全存储中,如数据库或密钥管理服务。

  • 创建API接口:创建一个受保护的API接口来向前端提供密钥。为了提高安全性,可设置此接口需要身份验证,以确保只有经过授权的用户或应用程序可以访问后端的密钥服务。

  • 前端请求密钥:前端通过已认证的请求来获取密钥。

       对于包含敏感信息的环境变量,应该避免将其暴露给前端。如果确实需要在前端使用某些敏感信息,考虑使用更安全的机制,比如客户端证书或令牌。

2. 配置文件存储

        将密钥存储在前端应用的配置文件中。在构建和部署应用时,可以将密钥配置为独立的配置文件,并在应用启动时读取配置文件中的密钥。

        但是,在前端应用中使用配置文件来存储密钥也不是一个好的做法,因为前端代码(包括配置文件)最终会被发送到用户的浏览器,这意味着任何有意图的攻击者都可以查看、修改甚至篡改这些配置。

3. 使用加密库加密存储

        将密钥进行加密,并将加密后的密钥存储在前端应用中,应用在运行时解密密钥并使用。

        这种方法可以提供更高的安全性,防止明文密钥泄露。

        常见的做法是使用对称加密算法,将密钥与应用内部的固定值进行加密存储,并在需要使用时进行解密。

  • 选择加密算法:选择一个适合的对称加密算法,例如 AES(高级加密标准)。AES 是一种常用的对称加密算法,提供了高强度的加密和解密功能。

  • 生成加密密钥:使用选择的算法生成加密密钥。

  • 加密密钥:将生成的加密密钥应用内部的某固定值进行加密,固定值可以是应用的特定字符串或其他数据。将加密后的密钥存储在前端应用中。

  • 解密密钥:在需要使用密钥的时候,通过解密算法对加密的密钥进行解密,获取原始的密钥值。解密过程需要使用相同的密钥和算法进行解密操作。

        以下是一个示例,展示如何使用 JavaScript 中的 CryptoJS 库进行加密和解密:

// 导入 CryptoJS 库
const CryptoJS = require('crypto-js');

// 固定值,用于加密密钥
const fixedValue = 'your_fixed_value';

// 原始密钥
const originalKey = 'your_secret_key_value';

// 加密密钥
const encryptedKey = CryptoJS.AES.encrypt(originalKey, fixedValue).toString();

// 解密密钥
const decryptedKey = CryptoJS.AES.decrypt(encryptedKey, fixedValue).toString(CryptoJS.enc.Utf8);

console.log(decryptedKey); // 输出原始密钥

        加密存储并不是绝对安全的,它只是增加了密钥泄露的难度。对于高安全性要求的应用,建议将敏感操作放在服务器端进行,避免将加密密钥暴露给前端应用的客户端。

4. 混淆技术

        混淆是防止JavaScript代码被轻易阅读和理解的有效方法,它通过一系列自动化的工具转换代码结构,但不改变其功能。混淆虽然提高了代码的保密性,但依然不能防止专业人员通过耐心分析来理解代码。因此,它更多是增加攻击者的分析成本,而不是绝对的保护措施。

        关于混淆,详细请看这篇:前端JavaScript代码混淆加密原理

5. 安全存储服务

        将密钥存储在专门的密钥管理服务中,如密钥管理系统(Key Management System,KMS)。前端应用在运行时通过安全的协议和认证机制与密钥管理服务通信,获取需要的密钥。这样可以将密钥的管理和保护责任交给专门的服务,提供更高级别的安全性。

        这也是一种将敏感数据安全地存储在后端服务器上的方法,以确保数据的保密性和完整性。

实际应用

        综合来看,相对比较安全的是方法1b和5。

        由于只是为了解决公司安全检测,故只选择了1a+3来存储密钥,其他方法可以考虑作为后续优化方向。

        其中CryptoJs库的使用:前端加密JS库--CryptoJS 使用指南

// ------------env.d.ts------------
declare const _MY_GLOBAL_KEY_: string

// ------------vite.config.ts------------
// base64加密后的密钥(注意,此处存储的密钥已经使用base64加密过了)
const PRIVATE_KEY = "'xxxxxxxxxxxx'"
export default defineConfig(({ command, mode }) => {
  return {
    // ......
    // 定义全局常量,用于环境变量注入或其他编译时替换
    define: {
      _MY_GLOBAL_KEY_: PRIVATE_KEY
    }
  }
})

// ------------crypto.js------------
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
const decryptKEY = CryptoJS.enc.Base64.parse(_MY_GLOBAL_KEY_).toString(CryptoJS.enc.Utf8) // Base64解密

// rsa解密
export function rsaDecrypt(decryStr) {
  const decryptor = new JSEncrypt()
  decryptor.setPrivateKey(decryptKEY)
  const decrypted = decryptor.decrypt(decryStr)
  return decrypted
}

// 发送请求获取token
getTokenApi()
  .then(res => {
    const { resultData } = res
    let decryptData = null
    try {
      decryptData = JSON.parse(CryptoJS.enc.Base64.parse(resultData).toString(CryptoJS.enc.Utf8))
    } catch (error) {
      console.log('error: ', error)
    }

    s3Data.value = decryptData
    s3Data.value.ak = rsaDecrypt(decryptData.ak) //RSA解密
    s3Data.value.sk = rsaDecrypt(decryptData.sk) //RSA解密

    formData.bucketName = s3Data.value.bucketName
    s3.value = new window.AWS.S3({
      accessKeyId: s3Data.value.ak,
      secretAccessKey: s3Data.value.sk,
      endpoint: s3Data.value.endpoint,
      sessionToken: s3Data.value.token
    })
  })
  .catch(err => {
    proxy.$errorHandle(err)
  })

拓展

Base64

        经常在提到加密算法时看到Base64的使用,Base64的输入是二进制数据,输出是字符串,它是一种将二进制数据转换为字符的方法。通过Base64编码出的字符串只包含ASCII基础字符,如小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"。

        例如:字符串ShuSheng007对应的Base64为U2h1U2hlbmcwMDc=。其中=比较特殊,是填充符。

        要注意的是,Base64不是加密算法,仅仅是一种编码方式,其算法也是公开的,所以并不能依赖它进行加密。

  • 为什么要在加密算法中使用Base64

        既然Base64不是加密算法,为什么加密算法又要使用它呢。

        我们知道加密是将明文、可读的数据转换为加密的、无法阅读的乱码。然而,加密的输出是包含不可打印字符的二进制数据。为了安全传输或存储这些加密数据,需要把他们编码为能够正常处理的 ASCII 字符串。这就是 Base64 编码在加密算法中的作用。

        此外,Base64编码是很适合在HTTP环境下使用的,因为HTTP是以传输文本为主的协议,而Base64算法正好可以把传输内容变成文本。

        而且由于base64的特性,其大小增加很有限,编码后,不会明显扩大原有文件的大小。

AES加密算法

        高级加密标准(AES,Advanced Encryption Standard)是最常见的对称加密算法。

        对称加密算法就是加密和解密用相同的密钥,具体的加密流程如下图:

明文P

        指没有经过加密的数据。

密钥K

         用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。

        密钥为接收方与发送方协商产生的,但不可以直接在网络上传输,否则会导致密钥泄漏。通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,对方再解密。

AES加密函数

        把明文P和密钥K作为加密函数的参数输入,则加密函数会输出密文C。

密文C

        经加密函数处理后的数据。

AES解密函数

        把密文C和密钥K作为解密函数的参数输入,则解密函数会输出明文P。

  • 对称加密与非对称加密的区别

对称加密算法

        对称加密算法的加密和解密用的密钥是相同的。这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是使用的密钥,它本身的传输比较麻烦,一般用非对称加密来传输。

非对称加密算法

        非对称加密算法的加密和解密用的密钥是不同的。通常加密解密的速度比较慢,适合偶尔发送数据的场合。可以用非对称加密算法来串数对称加密算法使用的密钥。常见的非对称加密算法为RSA、ECC和EIGamal。

       

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入了解 Three.js 中的材质与光照

开发领域:前端开发 | AI 应用 | Web3D | 元宇宙 技术栈:JavaScript、React、ThreeJs、WebGL、Go 经验经验:6年 前端开发经验,专注于图形渲染和AI技术 开源项目:github 晓智元宇宙、数字孪生引擎、前端面试题 大家好&am…

【Linux】网络基础常识{OSI七层模型 TCPIP 端口号 各种协议}_哪种nat类型适用于多个内部设备共享有限的公共ip地址

文章目录 1.网络常识 1.0DHCP协议1. 1IP地址/MAC地址/ARP协议是什么? IP/MACARP:IP ⇒ MAC 1.2手机连接wifi的原理 SSID与BSSID 手机连接wifiSSID与BSSID 1.3手机如何通过“数据/流量”上网?1.4电脑连接wifi的原理?电脑通过热点…

uniapp使用uni-push模拟推送

uniapp使用uni-push模拟推送 第一步先去uniapp开发者中心添加开通uni-push功能 这里的Android 应用签名可以先用测试的官网有,可以先用这个测试 官方测试链接文档地址 在项目中的配置文件勾选 组件中使用 如果要实时可以去做全局ws //消息推送模版uni.createPushMessage(…

ai画质修复工具有哪些?这4款AI照片修复神器建议收藏!

在当今这个科技迅猛发展的时代,人工智能(AI)正以前所未有的速度重塑我们的日常生活,而照片修复领域正是AI技术大放异彩的舞台。从年代久远、泛黄的老照片到追求极致细节的现代摄影佳作,AI以其非凡的能力,成…

MES管理系统在工艺管理中具备哪些作用

在现代制造业的洪流中,MES管理系统正逐步成为工艺管理领域的一股强大力量,它不仅革新了传统的管理方式,还为企业带来了前所未有的效率提升与成本控制优势。尽管许多企业尚未全面拥抱这一数字化变革,但MES管理系统在工艺管理中的潜…

IM_自定义audio播放消息

做即时通讯,除了文字、图片、表情、还有媒体消息,整理一下制作过程中自定义聊天框中的audio 效果图 tsx完整代码 AzEventBus 是解决点击多个语音播放时候,保证只有一个在播放;没什么特别的,就是自己简单封装了个EvenBusAzEventBus…

tcp shutdown, fin_wait1, fin_wait2, close_wait, last_ack, 谢特!

TCP 作为双向传输协议,如果你想只收不发,可以单向关掉发,shutdown(socket.SHUT_WR),但不建议这么做。 看以下代码: #!/Users/zhaoya/myenv/bin/python3 # client import socketclient_socket socket.socket(socket.…

怎么知道社媒上用户在讨论品牌什么?评价如何?

现在社交媒体不再仅是人们闲聊和分享生活片段的地方,更是品牌了解市场趋势和消费者需求的重要渠道。所以做号社媒上用户声音的聆听,企业更能抓住客户需求、抢占潜力市场,进一步占据更多市场份额,获得精准客户。 做好用户声音聆听…

【QT】Qt窗口(上)

个人主页~ Qt窗口 一、菜单栏二、工具栏三、状态栏四、浮动窗口五、对话框1、简介(1)模态对话框(2)非模态对话框(3)混合属性对话框 Qt窗口是通过QMainWindow类来实现的,我们之前的学习是通过QWi…

第二十章 Vue组件通信之父子通信

目录 一、引言 二、组件关系分类 三、组件通信的解决方案 3.1. 父子通信流程图 3.2. 父组件通过 props 将数据传递给子组件 3.2.1. 代码App.vue 3.2.2. 代码MySon.vue 3.3. 子组件利用 $emit 通知父组件修改更新 ​编辑3.3.1. 代码App.vue 3.3.2. 代码MySon.vue 3…

用ChatGPT提升工作效率:从理论到实际应用

伴人工智能技术的迅速演进,像ChatGPT这类语言模型已成为提升工作效率的关键工具。这类模型不仅具备处理海量数据的能力,还能自动化许多日常任务,从而提高决策的准确性。本文将深入探讨如何在工作中利用ChatGPT等AI工具提升效率,涵…

golang 服务注册与服务发现框架 入门与实践

Go语言中服务注册与发现的应用 在Go微服务架构中,服务注册与服务发现是实现服务间通信和解耦的关键。随着服务数量的增长,手动管理服务之间的依赖关系变得异常复杂且容易出错。因此,自动化服务注册与发现机制变得尤为重要。当一个Go微服务启…

1.STM32之定时器TIM---第一部分(基本定时器)(功能最强大结构最复杂的一个外设)(实验基本定时功能)-----定时器定时中断(利用内部时钟72M)

定时器TIM是STM32外设中功能最强大结构最复杂的一个外设!Whappy STM32F103C8T6总共由一个高级定时器3个通用定时器 #include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include &quo…

无人机救援系统基本组成

无人机救援系统基本组成 1. 源由2. 组成2.1 无人机载具2.1.1 多旋翼2.1.2 垂起固定翼2.1.3 智能避障2.1.4 物资投递 2.2 智能吊舱2.2.1 云台2.2.2 高清摄像2.2.3 红外热成像2.2.4 激光测距2.2.5 目标跟踪 2.3 通讯链路2.3.1 超长距离通信2.3.2 长距离通信2.3.3 中等距离通信 2.…

CSS 复习

复杂选择器可以通过(id的个数,class的个数,标签的个数)的形式,计算权重。 如果我们需要将某个选择器的某条属性提升权重,可以在属性后面写!important;注意!importent要写在;前面 很多公司不允许…

uniapp一键打包

1.先安装python环境, 2.复制这几个文件到uniapp项目里面 3.修改自己证书路径,配置文件路径什么的 4.在文件夹页面双击buildController.py或者cmd直接输入buildController.py 5.python报错,哪个依赖缺少安装哪个依赖 6.执行不动的话&…

SINAMICS V90 在汽车行业中的应用-天拓四方

随着生活水平的提高,平均每家每户都配有一辆代步用的小汽车,汽车行业也正处于蓬勃的发展中,尤其是新能源汽车,带来了新一轮的汽车生产热潮。生产一辆汽车,从零配件的加工,到整车的组装,基本已经…

C++算法第五天

本篇文章继续和大家一起刷算法题 第一题 题目链接 . - 力扣(LeetCode) 题目解析 题目要求: 这是一个连续的子数组 计算子数组内元素的和,若数组内元素的和符合 > target的值并且该子数组的长度是最短的,则返回…

【电机控制器】以STC8H1K系列举例——持续更新

【电机控制器】以STC8H1K08 举例——持续更新 文章目录 [TOC](文章目录) 前言一、代填二、参考资料总结 前言 使用工具: 提示:以下是本篇文章正文内容,下面案例可供参考 一、代填 二、参考资料 STC8H1K系列数据手册 梁工——BLDC, 三相无…

如何快速给word文件里的文字加拼音?请看详细步骤

怎么快速给word文件里的文字加拼音?在日常的文字处理工作中,很多人可能会遇到一个问题:如何在Word文档中为文字添加注音。尤其是对于一些需要帮助读音的文本,比如中文学习材料、教材或儿童读物,注音可以帮助读者更好地…