ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Node.js 进阶:基于 crypto 模块的 RSA 非对称加密与解密实战

Node.js 进阶:基于 crypto 模块的 RSA 非对称加密与解密实战 文档教程后端【免费下载链接】nodejs-learning-guideNodejs学习笔记以及经验总结公众号程序猿小卡项目地址https://gitcode.com/gh_mirrors/no/nodejs-learning-guide点击查看免费下载本文围绕 Node.js 核心模块crypto讲解如何通过公钥加密、私钥解密来完成非对称加密的完整流程。文中以公众号程序猿小卡在 Nodejs学习笔记 仓库中的实战代码为主线从 API 用法、Buffer 参数注意事项到可直接运行的完整示例帮助读者在 5 分钟内掌握 Node.js 中 RSA 非对称加解密的正确姿势并规避最常见的踩坑点。前言从一个常见问题说起非对称加密又称公开密钥加密是信息安全领域应用非常广泛的一类算法。所谓非对称指的是加密和解密所用的密钥不同用于加密的公钥public key可以公开分发而用于解密的私钥private key必须由接收方妥善保管。在 Node.js 中使用非对称加密负责安全的模块是内置的crypto。由于加解密 API 的参数要求比较隐蔽尤其是 Buffer 类型不少开发者在实际使用中会遇到解密出错的问题。本仓库的 进阶/asymmetric-enc-dec.md 正是针对这一类问题做的实战总结对应的完整可运行代码位于 examples/2018.01.28-asymmetric-enc-dec/包含utils.js、keys.js、app.js三个文件下面逐一展开。关于非对称加密背后的密码学理论如 RSA 的数学原理、摘要与 HMAC、数字签名等可以参考仓库中的理论篇 进阶/crypto-theory.md本文聚焦于怎么用。非对称加密的两个核心 API在 Node.js 的crypto模块中RSA 非对称加解密分别对应两个方法加密函数使用公钥crypto.publicEncrypt(key, buffer)解密函数使用私钥crypto.privateDecrypt(privateKey, buffer)两个 API 的参数类型需要特别留意publicEncrypt(key, buffer)第一个参数key为公钥字符串或 Buffer 均可第二个参数buffer为待加密的内容必须是Buffer 类型privateDecrypt(privateKey, buffer)第一个参数privateKey为私钥第二个参数buffer为待解密的密文必须是Buffer 类型。这正是初学者最容易踩坑的地方如果直接传入普通字符串解密或加密过程可能报错或产生不符合预期的结果。仓库 examples/2018.01.28-asymmetric-enc-dec/utils.js 的源码注释里明确写了两条约定加密时第二个参数是 Buffer 类型解密时encrypted是 Buffer 类型。加密/解密与签名/验证的关系很多同学会把加密/解密和签名/验证搞混。由于 RSA 算法的特殊性两者看上去非常相似这里先记住结论详细原理见 进阶/crypto-theory.md 中的数字签名章节加密/解密公钥加密私钥解密签名/验证私钥签名公钥验证。也就是说crypto.publicEncryptcrypto.privateDecrypt用于保护数据的机密性而crypto.createSigncrypto.createVerify用于确认信息来源与完整性。两者方向正好相反不要混淆。完整可运行的入门示例1. 封装加解密工具utils.js仓库将加解密逻辑封装成一个工具模块源码位于 examples/2018.01.28-asymmetric-enc-dec/utils.js完整的实现如下const crypto require(crypto); /** * 公钥加密 * param {String} plainText 待加密的明文 * param {Buffer} pubKey 公钥 * return {Buffer} 加密后的密文 */ exports.encrypt (plainText, pubKey) { return crypto.publicEncrypt(pubKey, Buffer.from(plainText)); }; /** * 公钥加密 * param {Buffer} encrypted 加密后的密文 * param {Buffer} privKey 私钥 * return {Buffer} 解密后的明文 */ exports.decrypt (encrypted, privKey) { return crypto.privateDecrypt(privKey, encrypted); };两个关键点加密前用Buffer.from(plainText)将字符串明文显式转换为 Buffer满足publicEncrypt对第二个参数必须是 Buffer 的要求publicEncrypt与privateDecrypt返回的也都是 Buffer因此解密后需要调用decrypted.toString()才能还原为可读字符串。2. 准备密钥对keys.js仓库将公钥、私钥以模板字符串的形式内联在 examples/2018.01.28-asymmetric-enc-dec/keys.js 中分别是 PEM 格式的 PKCS#1 私钥-----BEGIN RSA PRIVATE KEY-----和 PKCS#8 公钥-----BEGIN PUBLIC KEY-----exports.privKey -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDFWnl8fChyKI/Tgo1ILBIlGr8ZECKnnO8XRDwttBbf5EmG0qV 8gs0aGkh649rb75ItMu2JSNuVj61CncL/7Ct2kAZ6CZZo1vYgtzhlFnxd4V7Ra aIwLZaXT/h3eE/cFsL4VAJI5wXh4Mq4Vtu7uEjeogAOgXACaIqiFyrk3wIDAQAB ... -----END RSA PRIVATE KEY----- ; exports.pubKey -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFWnl8fChyKI/Tgo1ILBIlGr8 ... -----END PUBLIC KEY----- ;完整密钥内容请直接查看仓库文件。生产实践提示示例中密钥直接写死在代码里仅用于演示。真实项目中私钥应当存放在受保护的文件或密钥管理系统中通过fs.readFileSync等方式读取可参考仓库 examples/2016.12.12-node-crypto/sign/ 中fs.readFileSync(./private-key.pem)的读取方式切勿提交到版本库。3. 组装测试app.js测试入口 examples/2018.01.28-asymmetric-enc-dec/app.js 演示了完整的加密 → 解密 → 还原链路const utils require(./utils); const keys require(./keys); const plainText 你好我是程序猿小卡; const crypted utils.encrypt(plainText, keys.pubKey); // 加密公钥加密 const decrypted utils.decrypt(crypted, keys.privKey); // 解密私钥解密 console.log(decrypted.toString()); // 你好我是程序猿小卡4. 运行验证在仓库目录下进入示例文件夹并执行cd examples/2018.01.28-asymmetric-enc-dec node app.js正常输出你好我是程序猿小卡从输出可以看到明文你好我是程序猿小卡经过公钥加密 → 私钥解密后能够完整还原。由于该示例只依赖 Node.js 内置模块crypto无需npm install安装任何第三方依赖即可运行。常见踩坑与注意事项结合crypto模块的 API 约定和仓库源码使用非对称加解密时有以下几点需要格外注意1. 第二个参数必须是 BufferpublicEncrypt、privateDecrypt的第二个参数都要求是 Buffer。加密前记得用Buffer.from(data)做转换解密得到的结果是 Buffer展示给用户前要toString()。若把字符串直接当作密文/明文传入可能出现解密失败或输出乱码。2. 加密与解密必须使用匹配的密钥对公钥加密的密文只能用对应的私钥解开。示例中keys.pubKey与keys.privKey是同一对密钥如果混用其他密钥对解密会直接报错如ERR_OSSL_RSA_...一类的错误具体报错信息随 OpenSSL 版本不同而有差异。3. 私钥泄露 加密失效非对称加密的安全性完全建立在私钥保密之上。公钥可以公开但私钥一旦泄露任何持有私钥的人都能解开密文。这也是公钥加密、私钥解密设计的根本原因。4. 非对称加密的性能特征通常来说非对称加密的运算速度慢于对称加密如 AES、DES因此非对称加密通常用于加密短文本而长文本加密多用对称加密。两者可以结合使用例如 HTTPS 协议在握手阶段通过 RSA 这类非对称算法协商出对称密钥后续通信阶段再用对称加密算法加密数据详见 进阶/crypto-theory.md 中的对比与应用小节。关联阅读非对称加密的理论基础对称加密与非对称加密的对比、数字签名、分组加密模式等进阶/crypto-theory.mdcrypto 模块的完整 API 笔记hash、HMAC、加解密、数字签名、DiffieHellman 等模块/crypto.md数字签名私钥签名、公钥验证实战示例examples/2016.12.12-node-crypto/sign/sign.js本文示例的完整代码examples/2018.01.28-asymmetric-enc-dec/小结通过 Node.js 内置crypto模块进行非对称加解密其实非常方便公钥加密用crypto.publicEncrypt私钥解密用crypto.privateDecrypt只要把参数类型Buffer和密钥匹配关系这两点处理好就能在业务中安全、正确地使用 RSA 非对称加密。更多底层 API 的用法可以参考 Node.js 官方 crypto 文档以及本仓库 模块/crypto.md 的整理。赞分享文档教程后端【免费下载链接】nodejs-learning-guideNodejs学习笔记以及经验总结公众号程序猿小卡项目地址https://gitcode.com/gh_mirrors/no/nodejs-learning-guide点击查看免费下载相关推荐CryptoSwift数据填充与RSA非对称加密实战CryptoSwift数据填充与RSA非对称加密实战 本文深入探讨了CryptoSwift库中的数据填充方案实现原理和RSA非对称加密算法的Swift实现。首先密码学system-design-101 密码学基础对称加密与非对称加密的机制、取舍与 HTTPS 实战应用system design 101 密码学基础对称加密与非对称加密的机制、取舍与 HTTPS 实战应用 对称加密Symmetric Encryption与后端文档教程Geyser资源包实战指南3步让基岩版玩家看到与Java版一致的画面Geyser资源包实战指南3步让基岩版玩家看到与Java版一致的画面 你有没有遇到过这种场面Java端玩家放出的玩家头颅在基岩端变成了一块纯泥土或者精心挑网络游戏开发上一篇stb库调试终极指南7个技巧快速解决单文件库疑难问题下一篇PaddleSeg SemanticConnectivityLossSCL 语义连通性损失原理、源码解析与训练配置实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表