NodeJS 使用SHA 256签名与使用RSA-SHA 256签名

ncgqoxb0  于 2023-06-29  发布在  Node.js
关注(0)|答案(2)|浏览(320)

我用node.js玩数字签名。出于测试目的,我创建了一些XML数据的数字签名,首先只使用SHA 256,然后使用RSA-SHA 256。
令我困惑的是,两种签名方法创建的签名完全相同。两个签名完全相同。如果它们是相同的,那么为什么要使用两种不同的方法(SHA 256与RSA-SHA256)?
我在下面包含代码:

var crypto = require('crypto'),
    path   = require('path'),
    fs     = require('fs'),

    pkey_path = path.normalize('private_key.pem'),
    pkey = '';

function testSignature(pkey) {
    var sign1 = crypto.createSign('RSA-SHA256'),
        sign2 = crypto.createSign('SHA256');

    fs.ReadStream('some_document.xml')
        .on('data', function (d) {
            sign1.update(d);
            sign2.update(d);
        })
        .on('end', function () {
            var s1 = sign1.sign(pkey, "base64"),
                s2 = sign2.sign(pkey, "base64");

            console.log(s1);
            console.log(s2);
        });
}

// You need to read private key into a string and pass it to crypto module.
// If the key is password protected, program execution will stop and
// a prompt will appear in console, awaiting input of password.

testSignature(fs.readFileSync(pkey_path));

上面的代码输出了一些字符串,这是签名,然后又是完全相同的字符串,这也是相同数据的签名,但使用-据说-不同的算法创建,但它与前一个相同...

qco9c6ql

qco9c6ql1#

签名不能单独由SHA 256创建。
SHA 256是一种哈希算法;即创建表示任意大量数据的短指纹数的算法。为了生成签名,仍然必须以某种方式处理该指纹,以允许识别某个私人签名密钥的保持器。一种这样的处理是使用rsa密钥对的私钥加密指纹,允许其他人使用相关的公钥解密结果,从而验证私钥的持有者确实必须是签名者。
在加密API的上下文中,RSA加密方案要么是默认的处理方法(当处理方法没有显式命名时),要么是从您在sign调用中用作参数的私钥推导出的处理方法--如果它是RSA私钥,则使用RSA;如果是DSA密钥,则使用DSA;...

zqry0prt

zqry0prt2#

您看到的是PKCS#1 v1.5签名的两倍。这是一个确定性的签名方案,因此它总是返回相同的结果(将其与PSS方案进行比较,后者是随机的,提供了更好的安全属性)。RSA PKCS#1 v1.5签名生成和PSS签名生成在RFC 3447(也称为RSA v2.1规范)中定义。
如果您使用RSA 512位的代码(仅用于测试目的,使用2048位或以上的密钥),则会得到以下结果:
私钥:

-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBALLA/Zk6+4JFJ+XdU6wmUkuEhGa8hLZ+m6J3puZbc9E+DSt7pW09
yMYwHF5MMICxE86cA6BrLjQLUUwvquNSK0ECAwEAAQJAcI/w4e3vdRABWNFvoCcd
iWpwSZWK6LR/YuZ/1e1e2DJw+NXyPXbilSrLvAdxnjlWTsTxUiEy1jFh36pSuvMk
AQIhAO4WtgysOoWkyvIOLIQwD0thWfdHxTpxqfd6flrBJ91hAiEAwDOQqHhnSeET
+N/hwUJQtCkHBJqvMF/kAi4Ry5G+OeECIEg1Exlc0pLdm781lUKx4LGX4NUiKyrC
di3cNJ4JnrGBAiEAi2gbYYbLbDO8F8TTayidfr9PXtCPhyfWKpqdv6i7cCECIH7A
6bh0tDCl6dOXQwbhgqF4hXiMsqe6DaHqIw8+XLnG
-----END RSA PRIVATE KEY-----

作为base 64签名(使用您的代码):

YY6sur9gkHXH23cUbDMYjCJYqDdBK8GKp4XyRNl8H09cW8H/gKQI9Z6dkLMhNh7oPq1yABCRfTP8yRtfLVj7FA==

和十六进制

618eacbabf609075c7db77146c33188c2258a837412bc18aa785f244d97c1f4f5c5bc1ff80a408f59e9d90b321361ee83ead720010917d33fcc91b5f2d58fb14

使用RAW RSA解密(即仅使用公共指数进行模幂运算):

0001ffffffffffffffffffff003031300d0609608648016503040201050004202af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64

这是一个 *PKCS#1 v1.5签名 * 的非常清晰的例子,很容易通过FF填充识别,然后是ASN.1结构(以30,SEQUENCE开始):

SEQUENCE (2 elem)
  SEQUENCE (2 elem)
  OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) sha256(1)}
    NULL
  OCTET STRING(32 byte) 2AF565B95E5F4479492C520C430F07AE05D2BCFF8923322E6F2EF6404D72AC64

所以最后的是散列,在这个例子中,只是some_document.xml文件中的Test 123\n,因为我今天不想输入任何XML。

$ sha256sum some_document.xml 
2af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64  some_document.xml

相关问题