gpt4 book ai didi

javascript - 在 node.js 中验证 PKCS#7 (PEM) 签名/解包数据

转载 作者:IT老高 更新时间:2023-10-28 23:15:57 33 4
gpt4 key购买 nike

我从第 3 方系统获得 PKCS#7 加密包。该包未压缩,未加密,PEM 编码,使用 X.509 证书签名。我还有来自提供商的 PEM 证书文件。

里面的数据是XML

我需要在 Node.JS 中执行以下操作:

  • 提取数据
  • 验证签名

一个示例包(没有敏感信息,数据引用我们的质量保证系统)http://pastebin.com/7ay7F99e

最佳答案

好的,终于明白了。

首先,PKCS 消息是使用 ASN1 二进制编码的复杂结构。 .

其次,它们可以序列化为二进制文件 (DER encoding) 或使用 Base64 的文本 PEM 文件编码。

第三,PKCS#7 format指定几个包类型,其中 my 被称为签名数据。这些格式通过 ASN1 对象(包装器序列的第一个元素)开头的 OBJECT IDENTIFIER 值来区分 — 您可以转到 http://lapo.it/asn1js/并粘贴 package text对于完全解析的结构。

接下来,我们需要解析包(Base64 -> ASN1 -> 一些对象表示)。不幸的是,没有 npm 包。我发现了一个很好的项目forge未发布到 npm 注册表(尽管与 npm 兼容)。它解析了 PEM 格式,但是遍历生成的树是一件非常不愉快的事情。基于他们的 Encrypted Data 和 Enveloped Data 实现,我在自己的 fork 中创建了 Signed Data 的部分实现。 UPD:我的拉取请求后来被合并到了 forge 项目中。

现在我们终于解析了整个内容。那时,我发现了一篇关于签名 PKCS#7 验证的精彩文章(可能是整个网络上唯一的):http://qistoph.blogspot.com/2012/01/manual-verify-pkcs7-signed-data-with.html

我能够从文件中提取并成功解码签名,但其中的哈希与数据的哈希不同。上帝保佑克里斯explained实际发生了什么。

数据签名过程分为两步:

  1. 计算原始内容的哈希
  2. 构建了一组“授权属性”,包括:签名数据的类型、签名时间和数据哈希

然后使用签名者的私钥对步骤 2 中的集合进行签名。

由于 PKCS#7 的具体规定,这组属性存储在特定于上下文的构造类型(class=0x80,type=0)内,但应作为普通 SET(class=0,type=17)进行签名和验证.

正如 Chris 提到的 (https://stackoverflow.com/a/16154756/108533 ),这仅验证包中的属性是否有效。我们还应该根据摘要属性验证实际数据哈希。

所以最后这是一个验证代码(cert.pem 是提供商发送给我的证书文件,package 是我从他们那里得到的 PEM 编码消息HTTP POST):

var fs = require('fs');
var crypto = require('crypto');
var forge = require('forge');
var pkcs7 = forge.pkcs7;
var asn1 = forge.asn1;
var oids = forge.pki.oids;

var folder = '/a/path/to/files/';
var pkg = fs.readFileSync(folder + 'package').toString();
var cert = fs.readFileSync(folder + 'cert.pem').toString();


var res = true;

try {
var msg = pkcs7.messageFromPem(pkg);
var attrs = msg.rawCapture.authenticatedAttributes;
var set = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, attrs);
var buf = Buffer.from(asn1.toDer(set).data, 'binary');

var sig = msg.rawCapture.signature;

var v = crypto.createVerify('RSA-SHA1');
v.update(buf);
if (!v.verify(cert, sig)) {
console.log('Wrong authorized attributes!');
res = false;
}

var h = crypto.createHash('SHA1');
var data = msg.rawCapture.content.value[0].value[0].value;
h.update(data);

var attrDigest = null;
for (var i = 0, l = attrs.length; i < l; ++i) {
if (asn1.derToOid(attrs[i].value[0].value) === oids.messageDigest) {
attrDigest = attrs[i].value[1].value[0].value;
}
}

var dataDigest = h.digest();
if (dataDigest !== attrDigest) {
console.log('Wrong content digest');
res = false;
}

}
catch (_e) {
console.dir(_e);
res = false;
}

if (res) {
console.log("It's OK");
}

关于javascript - 在 node.js 中验证 PKCS#7 (PEM) 签名/解包数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15969733/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com