Ari*_*rim 1 rsa sha256 digital-signature node.js
我使用node.js 玩数字签名.出于测试目的,我创建了一些XML数据的数字签名,首先只使用SHA256,然后使用RSA-SHA256.
令我困惑的是,两种签名方法都创建了完全相同的签名.两个签名都是相同的.如果它们相同,那么为什么有两种不同的方法(SHA256与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));
Run Code Online (Sandbox Code Playgroud)
上面的代码输出一些字符串,这是签名,然后再次完全相同的字符串,这也是相同数据的签名,但创建 - 据说 - 不同的算法,但它与前一个相同...
mkl*_*mkl 13
SHA256无法单独创建签名.
SHA256是一种散列算法; 即,创建表示任意大量数据的短指纹数的算法.为了产生签名,仍然必须以某种方式处理该指纹以允许识别某个私人签名密钥的持有者.一种这样的处理是使用rsa密钥对的私钥加密指纹,允许其他人使用相关的公钥解密结果,并因此验证私钥的管理者确实必须是签名者.
在您的加密API的上下文中,当未明确命名处理时,RSA加密方案是默认处理,或者从您在sign调用中用作参数的私钥推导出的处理类型- 如果它是RSA私钥,它使用RSA; 如果是DSA密钥,则使用DSA; ...
您正在查看的是 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-----
Run Code Online (Sandbox Code Playgroud)
签名为 base 64(使用您的代码):
YY6sur9gkHXH23cUbDMYjCJYqDdBK8GKp4XyRNl8H09cW8H/gKQI9Z6dkLMhNh7oPq1yABCRfTP8yRtfLVj7FA==
Run Code Online (Sandbox Code Playgroud)
和十六进制
618eacbabf609075c7db77146c33188c2258a837412bc18aa785f244d97c1f4f5c5bc1ff80a408f59e9d90b321361ee83ead720010917d33fcc91b5f2d58fb14
Run Code Online (Sandbox Code Playgroud)
使用 RAW RSA 解密(即只是使用公共指数进行模幂运算):
0001ffffffffffffffffffff003031300d0609608648016503040201050004202af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64
Run Code Online (Sandbox Code Playgroud)
这是一个非常清晰的 PKCS#1 签名示例,很容易被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
Run Code Online (Sandbox Code Playgroud)
所以最后就是散列,在这种情况下,就像Test 123\n我今天不想输入任何 XML 一样。
$ sha256sum some_document.xml
2af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64 some_document.xml
$ sha256sum some_document.xml
2af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64 some_document.xml
Run Code Online (Sandbox Code Playgroud)