node.js - Node.js + 加密签名并通过 express 验证数据
问题描述
我希望能够确保公钥和私钥是有效的。我会将公钥存储在服务器上,而不是用户上传的每个请求。但是,将不允许发送。
server.js(服务器)
const express = require('express')
const crypto = require("crypto")
const fetch = require("node-fetch")
const app = express()
const port = 3002
app.get('/', async (req, res) => {
var res2 = await fetch('http://localhost:3001/data')
var verifiableData = await res2.text()
var res2 = await fetch('http://localhost:3001/key')
var publicKey = await res2.text()
var res2 = await fetch('http://localhost:3001/sig')
var signature = await res2.text()
const isVerified = crypto.verify(
"sha256",
Buffer.from(verifiableData),
{
key: publicKey,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
},
signature
)
res.send(isVerified)
})
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}`)
})
index.js(客户端)
const express = require('express')
const crypto = require("crypto")
const app = express()
const port = 3001
const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
// The standard secure default length for RSA keys is 2048 bits
modulusLength: 2048,
})
const verifiableData = "this need to be verified"
const signature = crypto.sign("sha256", Buffer.from(verifiableData), {
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
})
app.get('/data', (req, res) => {
res.send(verifiableData)
})
app.get('/sig', (req, res) => {
res.send(signature.toString("base64"))
})
app.get('/key', (req, res) => {
res.send(publicKey)
})
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}`)
})
我知道我应该从服务器而不是客户端请求信息,但我只是想让它工作。
我在 server.js 代码中遇到了这个错误signature
(node:19312) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_TYPE]: The "signature" argument must
be an instance of Buffer, TypedArray, or DataView. Received type string ('OFEush86vZIuFnTLFBiFt4Be...)
at Object.verifyOneShot [as verify] (internal/crypto/sig.js:212:11)
at C:\Users\user\Documents\coding\nodestuff\stesting\server\server.js:20:31
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:19312) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:19312) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise
rejections that are not handled will terminate the Node.js process with a non-zero exit code.
将 index.js 更新为
app.get('/sig', (req, res) => {
res.send(signature.toString("base64"))
})
和 server.js 到
const isVerified = crypto.verify(
"sha256",
Buffer.from(verifiableData),
{
key: publicKey,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
},
Buffer.from(signature, 'base64')
)
然后得到这个错误:
(node:5580) UnhandledPromiseRejectionWarning: Error: error:0909006C:PEM routines:get_name:no start line
at Object.verifyOneShot [as verify] (internal/crypto/sig.js:219:10)
at C:\Users\user\Documents\coding\nodestuff\stesting\server\server.js:20:31
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:5580) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:5580) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
它在单个文件中工作得非常好,只是在通过快速 API 发送时不起作用。如何修复错误/错误?
解决方案
需要做的是publicKey无效。这是因为它的PublicKeyObject
含义是不会使用 express 发送,而将值保留为{}
我必须做
const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
// The standard secure default length for RSA keys is 2048 bits
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
modulusLength: 2048,
})
以及在签名部分使用它。
Buffer.from(signature, 'base64')
推荐阅读
- android - android.database.sqlite.SQLiteException:靠近“,”:语法错误
- python-3.x - 如何在 Python 中手动排列 Value_counts 的索引
- asp.net - 使用 azure ad 和 db 的基于角色的身份验证
- c# - AppDomain.CurrentDomain.GetAssemblies() 返回的程序集的顺序
- nginx - 无法配置 Kubernetes nginx 入口基本身份验证
- quarkus - 在 quarkus 中测试时验证模拟用户
- python - NLP中如何判断句子是否带有情感?
- jupyter-notebook - Jupyter Notebook 验证失败
- php - 我面临“如果”解析错误:语法错误,意外的“如果”(T_IF)检查用户凭据。这是一个简单的登录页面。感谢你帮助我
- java - Java 泛型类类型一致性