【问题标题】:Prepare signing/verifying module from node js crypto从节点 js 加密准备签名/验证模块
【发布时间】:2021-07-04 10:26:59
【问题描述】:

我正在开发一个用于签名/验证的节点加密模块。我已经管理了验证模块:

'use strict';

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

const publicKey = fs.readFileSync(path.join(__dirname, 'key.pub'));
const encryptDataPath = path.join(__dirname, 'encryptData.txt');
let encryptData = fs.readFileSync(encryptDataPath).toString();

//console.log(encryptData);


// start decoding
const plainEncryptData = Buffer.from(encryptData, 'base64').toString();


const [signatureb64, contentb64] = plainEncryptData.split('\n');


const signature = Buffer.from(signatureb64, 'base64');
const content = Buffer.from(contentb64, 'base64').toString();

const verifier = crypto.createVerify('RSA-SHA256');
verifier.update(content);
verifier.end();

const isValid = verifier.verify(publicKey, signature);

if (!isValid) {
    console.log('not valid');
} else {    
    console.log(content);
}

这是公钥(pub.key):

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApuI1XlPkYos3WsSeVPtS
l1Q2k8GnLEO5vFZ4EuSghMbqI+yE0tWVEaiptdV3KgERaALRXmH+IFrHqvSRjKQC
1ORUarBU5ntWbNEr713R3K0BPOzz9OOoWHdk+Wmr4ViOTk0iD1u4bw/97RpyMoBm
+pXeBLHbEESK2kelk+LEmKUoY5nXp6KzZV5wxgD5QweZheU7mjXL5WMpIBJva8kp
RZMYXEF+uSZIep0q5FHEo2AazGUMAU3GjY/dpXisLmtleOa1xlKZmkvaXl/D2Mhb
BBqPbDMa72ToZg2J8K5UP9zXUP41FHr7o9rwSJ2uOkuZPg5nhDXeoVbrJwxP/U1M
nQIDAQAB
-----END PUBLIC KEY-----

这里是 encryptData.txt(加密数据)

ZmZzeUNhcmU2Q1pTRHo2M0VrT0tGeGJUWitDMGJydnF0dzRWZDc5STJIUTJuWndPZzVoaE8rbU5keEhIMHBEak0xVUxHRGNYQ0w1Wk5maVN4M096dDJXZEowSmk4R1pGZTZOc0s1dm05SDJHd1hUR3Q0VHl1ejFkbGlqbjRwcTBSM0xLSDl6SThWT1RLNTdySWlGeVZQa0pxQzJJMkowaW1LYTZxbWpGU0hsVTVQU3BrVk9YYUxGMVJNQjBsWm5ncDcwMEJXT1k4V3FlSHlvS0pKY0NXTkpJRGRDWEw1ZWpuTXFpY0VUTzZWV25BMThkVitRQUZRS2k5SG5SR1VuVGhlYUI2QU9jcWRzMGZzWVlvM0xZZlQwbDZELzJHd0dJZXZ3LzlxMmoxVmJKcFNBUTBldTJYUlJ4Z2VFZmFlQys0MUZIZ0haNHc4UXBmb09leW1WSkN3PT0KZXlKMGVYQmxJam9pWW5KdmJucGxJaXdpWTNWemRHOXRaWEpKWkNJNklqRTJRMDlXVWxOak9YZ3lNV1pEU0c1Rklpd2laWGh3YVhKbFFYUWlPakUyTWpZMU56WXpOakl3TURBc0ltbHpWSEpwWVd3aU9uUnlkV1VzSW14cFkyVnVjMlZMWlhraU9pSmpPVEk1TldJMk9TMWlaV1UyTFRRek1XRXRPR1EzWkMwd1lqYzBNR1l3TVdOaE1tUWlMQ0pqY21WaGRHVmtRWFFpT2pFMk1qVXpOalkzTmprMU16Rjk=

现在,我正在尝试创建其签名模块,该模块将创建与 encryptData.txt 相同的加密数据:

'use strict';

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

const publicKey = fs.readFileSync(path.join(__dirname, 'key.pub'));

let content = {}
content.type = "bronze";
content.customerId = "16COVRSc9x21fCHnE";
content.expireAt = 1626576362000;
content.isTrial = true;
content.licenseKey = "c9295b69-bee6-431a-8d7d-0b740f01ca2d";
content.createdAt = 1625366769531;


const encryptDataPath = path.join(__dirname, 'encryptData.txt');
let a = fs.readFileSync(encryptDataPath).toString();

// signing
const signer = crypto.createSign('RSA-SHA256');
signer.update(content);
signer.end();

const signature = signer.sign(publicKey, 'base64');

console.log('sign: ', signature);
 

但是当我运行这个加密模块时,它会抛出这个错误:

internal/crypto/util.js:97
    throw new ERR_INVALID_ARG_TYPE(
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be one of type string, Buffer, TypedArray, or DataView. Received type object
    at Sign.update (internal/crypto/sig.js:49:10)
    at Object.<anonymous> (/home/ubuntu/www/node-encrpt/encode.js:23:8)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
    at Module.load (internal/modules/cjs/loader.js:815:32)
    at Function.Module._load (internal/modules/cjs/loader.js:727:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
    at internal/main/run_main_module.js:17:11 {
  code: 'ERR_INVALID_ARG_TYPE'
}

我不知道为什么会这样。

如何完成加密模块?

【问题讨论】:

  • 这不是关于加密/解密,而是关于签名/验证。这是两个完全不同的东西。顺便说一句,签名是使用私钥而不是公钥完成的。公钥用于验证。
  • 谢谢@user9014097,我已经更新了问题标题。我可以使用任何私钥生成相同的 encryptedData.txt 吗?
  • encryptData.txt 包含一些数据及其签名。因此,相同的 encryptData.txt 意味着相同数据的相同签名。签名又取决于密钥、数据和填充。在代码中使用了 PKCS#1 v1.5 填充。这将为相同的密钥和相同的数据创建相同的签名。 IE。如果您应用在 encryptData.txt 中创建签名的私钥,则可以为相同的数据创建相同的签名。
  • @user9014097 我可以使用const signature = Buffer.from(signatureb64, 'base64'); 来生成私钥吗?我不知道,我怎样才能制作那个私钥?
  • 您不能简单地从签名和/或公钥重建私钥。如果这是可能的,那么不对称程序将毫无意义。

标签: javascript node.js encryption signing


【解决方案1】:

嗯,错误很简单:这一行...

signer.update(content);

... 尝试处理一个对象(content 的值),但它不能:update 不希望关心传递数据的正确序列化。由您决定如何处理。

一种常见的方法是使用 JSON 作为序列化格式:

signer.update(JSON.stringify(content));

但事实上,您可以使用任何能够将对象的内容映射到字符串、Buffer、TypedArray 或 DataView 的函数。这些是signer.update() 所期望的唯一类型。

【讨论】:

  • 现在又抛出一个错误:internal/crypto/sig.js:84 const ret = this[kHandle].sign(data, format, type, passphrase, rsaPadding
  • 您使用的公钥/私钥的格式是什么?
猜你喜欢
  • 2018-11-03
  • 1970-01-01
  • 2018-02-26
  • 2014-02-21
  • 1970-01-01
  • 1970-01-01
  • 2019-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多