node中的crypto模块指南

node中的crypto模块指南

加密操作可能很棘手,以至于付费的加密服务公司的存在只是为了确保在代码库中正确实现加密操作。好消息是,只需学习一些知识,我们就可以使用 Node 的内置加密模块免费进行适当的加密。

在本指南中,我们将探讨如何使用 Node 的内置加密模块正确执行(对称)加密/解密操作,以保护应用程序的数据。

首先,我们需要了解对称加密的概念。

对称加密

当人们谈论“加密”时,他们往往指的是对称加密,这对于将文本加密为随机字符串非常有用。与此相关的一个常见场景是对服务器上的用户数据进行加密,以便将其“静态加密”存储在数据库中。

通俗地说,对称加密就是获取要加密的文本(称为明文),并使用带有加密算法的密钥来输出加密文本(称为密文)。该操作是可逆的,因此解密是我们可以使用与明文相同的密钥。

在这里插入图片描述
看起来很容易吧?

但是当真正需要实现对称加密时,开发人员经常会犯错误,因为有很多东西需要理解:

  • 编码格式:数据可以通过多种方式进行编码/解码,例如base64hex等。当从一种格式转换为另一种格式时,这些不同的表示方式常常使开发人员感到困惑。
  • 算法和配置:有许多加密算法需要考虑,例如aes-256-gcmaes-256-cbc,每种算法都有自己的要求。
  • 随机性:加密过程中使用的密钥应随机生成,以确保高熵。很多时候,开发人员认为他们正在生成足够随机的密钥,但事实并非如此。
  • 复杂性:Node.js 中的加密涉及几个步骤,这些步骤对开发人员来说并不总是直观的,而且有些概念一开始确实令人费解。以初始化向量(IV)的概念为例;刚接触密码学的开发人员经常在加密过程中重复使用这些内容,这是一个很大的禁忌。

无论如何,在本文中并不会讨论上述细微差别,但更多地关注我们如何通过示例使用 Node.js 正确执行加密。

解释如何正确执行加密的最佳方法是演示使用aes-256-gcm算法的正确实现。让我们从加密开始。

加密

const crypto = require('crypto');const encryptSymmetric = (key, plaintext) => {const iv = crypto.randomBytes(12).toString('base64');const cipher = crypto.createCipheriv("aes-256-gcm", Buffer.from(key, 'base64'), Buffer.from(iv, 'base64'));let ciphertext = cipher.update(plaintext, 'utf8', 'base64');ciphertext += cipher.final('base64');const tag = cipher.getAuthTag()return { ciphertext, tag }
}const plaintext = "encrypt me";
const key = crypto.randomBytes(32).toString('base64');const { ciphertext, iv, tag } = encryptSymmetric(key, plaintext);

要执行加密,我们需要两项:

  • plaintext:要加密的文本。
  • key:256 位加密密钥。

我们从加密中得到以下输出:

  • ciphertext:加密文本。
  • iv:一个 96 位初始化向量,用于提供加密的初始状态,并允许在未来的加密操作中以不同iv重复使用相同key
  • tag:在加密过程中生成的一段数据,用于帮助验证加密文本在稍后的解密过程中没有被篡改。

让我们看一下代码:

const plaintext = "encrypt me";
const key = crypto.randomBytes(32).toString('base64');

这里我们定义执行加密所需的输入变量。除了要加密的文本之外,生成随机数以通过更高的熵key确保安全性也很重要;我更喜欢使用内置crypto.randomBytes()来生成。我还将所有内容转换为base64格式,因为它在概念上易于存储。

接下来我们来剖析一下加密函数:

const encryptSymmetric = (key, plaintext) => {// 创建随机初始化向量const iv = crypto.randomBytes(12).toString('base64');// 创建一个密码对象const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);// 使用明文更新 cipher 对象以进行加密let ciphertext = cipher.update(plaintext, 'utf8', 'base64');// 完成加密过程ciphertext += cipher.final('base64');// 检索加密的身份验证标签const tag = cipher.getAuthTag();return { ciphertext, iv, tag };
}

在这里,加密函数在使用aes-256-gcm(可以将其视为一种加密算法)算法、keyiv``crypto.createCipheriv初始化期间创建一个新的密码。下一部分加载要加密的文本plaintext并执行加密并检索身份验证标记,可以使用该标记来检查ciphertext解密过程中文本未被篡改。

关于加密,我们应该了解的最后一件事是如何处理数据。在加密用户数据并静态存储它的情况下,需要将加密的数据ciphertextiv、 和tag存储在数据库中,并将密钥安全地存储在其他地方,例如服务器上的环境变量。当我们想要检索数据时,可以从数据库中查询并使用密钥对其进行解密。

说到这里,让我们深入解密。

解密

const decryptSymmetric = (key, ciphertext, iv, tag) => {const decipher = crypto.createDecipheriv("aes-256-gcm", Buffer.from(key, 'base64'),Buffer.from(iv, 'base64'));decipher.setAuthTag(Buffer.from(tag, 'base64'));let plaintext = decipher.update(ciphertext, 'base64', 'utf8');plaintext += decipher.final('utf8');return plaintext;
}const plaintext = decryptSymmetric(key, ciphertext, iv, tag);

要执行解密,我们需要四项:

  • key:用于加密原始文本的256位加密密钥。
  • ciphertext:要解密的密文。
  • iv:加密期间使用的 96 位初始化向量。
  • tag:加密时生成的标签。

我们从加密中得到以下输出:

  • plaintext:我们加密的原始文本。

让我们看一下解密函数:

const decryptSymmetric = (key, ciphertext, iv, tag) => {// 创建一个解密对象const decipher = crypto.createDecipheriv("aes-256-gcm", Buffer.from(key, 'base64'),Buffer.from(iv, 'base64'));// 设置解密对象 decipher 的认证标签decipher.setAuthTag(Buffer.from(tag, 'base64'));// 使用 Base64 编码的密文更新解密对象let plaintext = decipher.update(ciphertext, 'base64', 'utf8');// 完成解密plaintext += decipher.final('utf8');return plaintext;
}

这里,解密函数在用aes-256-gcm算法进行crypto.createDecipheriv初始化时创建了一个解密对象,keyiv是之前创建的。接下来设置身份验证标签,用于检查是否被ciphertext篡改,最后我们执行解密以获得原始文本。

最后,我们的数据的安全程度取决于用于加密数据的密钥。因此,强烈建议安全地存储加密密钥,并在应用程序中将它们作为环境变量进行访问。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【腾讯云TDSQL-C Serverless 产品体验】使用 Python向TDSQL-C添加读取数据实现词云图

关于TDSQL-C Serverless介绍 TDSQL-C 是腾讯云自主研发的新一代云原生关系型数据库。 它融合了传统数据库、云计算和新硬件技术的优势,100%兼容 MySQL,为用户提供具有极致弹性、高性能、高可用性、高可靠性和安全性的数据库服务。 TDSQL-C 实现了超过百万每秒的高吞吐量,支持…

智能工业通信解决方案!钡铼BL124实现Modbus转Ethernet/IP互联!

钡铼技术BL124 Modbus转Ethernet/IP协议网关是一款专为工业自动化领域而设计的先进设备。它提供了可靠的通信解决方案,能够将Modbus通信协议与Ethernet/IP通信协议进行高效转换,实现不同类型设备之间的无缝集成和通信。 添加图片注释,不超过 …

MyBatisPlus(十六)逻辑删除

说明 实际生产中的数据,一般不采用物理删除,而采用逻辑删除,也就是将一条记录的状态改为已删除。 逻辑删除,本质上是更新操作。 MyBatis Plus 框架,提供了逻辑删除功能。在配置了逻辑删除后,增删改查和统…

记一次 .NET某账本软件 非托管泄露分析

一:背景 1. 讲故事 中秋国庆长假结束,哈哈,在老家拍了很多的短视频,有兴趣的可以上B站观看:https://space.bilibili.com/409524162 ,今天继续给大家分享各种奇奇怪怪的.NET生产事故,希望能帮助…

车载通信架构 —— DDS协议介绍

车载通信架构 —— DDS协议介绍 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和…

[PyTorch][chapter 57][WGAN-GP 代码实现]

前言: 下图为WGAN 的效果图: 绿色为真实数据的分布: 8个高斯分布 红色: 为随机产生的数据分布,跟真实分布基本一致 WGAN-GP: 1 判别器D: 最后一层去掉sigmoid 2 生成器G 和判别器D: loss不取log 3 损失函数…

OpenCV C++ Look Up Table(查找表)

OpenCV C Look Up Table(查找表) 引言 在图像处理和计算机视觉中,查找表(Look Up Table, LUT)是一种非常高效和实用的方法,用于快速地映射或更改图像的颜色和像素值。LUT 能够极大地提高图像处理算法的执…

【C++设计模式之解释器模式:行为型】分析及示例

简介 解释器模式(Interpreter Pattern)是一种行为型设计模式,它提供了一种解决问题的方法,通过定义语言的文法规则,解释并执行特定的语言表达式。 解释器模式通过使用表达式和解释器,将文法规则中的句子逐…

【java基础学习】之DOS命令

#java基础学习 1.常用的DOS命令: dir:列出当前目录下的文件以及文件夹 md: 创建目录 rd:删除目录cd:进入指定目录 cd.. :退回到上级目录 cd\ : 退回到根目录 del:删除文件 exit:退出dos命令行 1.dir:列出当前目录下的文件以及文件夹 2.md: 创建目录 …

【kubernetes】带你了解k8s中PV和PVC的由来

文章目录 1 为什么需要卷(Volume)2 卷的挂载2.1 k8s集群中可以直接使用2.2 需要额外的存储组件2.3 公有云 2 PV(Persistent Volume)3 SC(Storage Class) 和 PVC(Persistent Volume Claim)4 总结 1 为什么需要卷(Volume) Pod是由一个或者多个容器组成的,在启动Pod中…

Logback日志框架使用详解以及如何Springboot快速集成

Logback简介 日志系统是用于记录程序的运行过程中产生的运行信息、异常信息等&#xff0c;一般有8个级别&#xff0c;从低到高为All < Trace < Debug < Info < Warn < Error < Fatal < OFF off 最高等级&#xff0c;用于关闭所有日志记录fatal 指出每个…

【Java】微服务——RabbitMQ消息队列(SpringAMQP实现五种消息模型)

目录 1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯 1.2.技术对比&#xff1a; 2.快速入门2.1.RabbitMQ消息模型2.4.1.publisher实现2.4.2.consumer实现 2.5.总结 3.SpringAMQP3.1.Basic Queue 简单队列模型3.1.1.消息发送3.1.2.消息接收3.1.3.测试 3.2.WorkQueue3.…