使用SHA256进行签名与使用RSA-SHA256进行签名之间的区别

我使用node.js玩数字签名 出于testing目的,我创build了一些XML数据的数字签名,首先使用SHA256,然后使用RSA-SHA256。

令我感到困惑的是, 两种签名方法都创build了完全相同的签名 。 两个签名是相同的。 如果它们是相同的,那么为什么两种不同的方法(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)); 

上面的代码输出一些string,这是签名,然后又是完全相同的string,这也是相同数据的签名,但创build – 据推测 – 不同的algorithm,但它与以前的一个相同…

签名不能由SHA256单独创build。

SHA256是一种哈希algorithm; 即创build代表任意大量数据的短指纹数的algorithm。 为了产生一个签名,这个指纹还需要以某种方式处理,以便识别一些私人签名密钥的持有者。 一种这样的处理是使用rsa密钥对的私钥对指纹进行encryption,从而允许其他人使用相关联的公钥对结果进行解密,从而validation私钥的保pipe者确实一定是签名者。

在你的密码API的情况下,RSAencryptionscheme要么是未明确命名治疗的默认治疗方法,要么是从你在sign调用中用作参数的私钥推导治疗方式—如果是RSA私钥,它使用RSA; 如果它是DSA密钥,则使用DSA; …

您所看到的是PKCS#1 v1.5签名的两倍。 这是签名的确定性scheme,所以它总是返回相同的结果(将其与PSSscheme进行比较,该scheme是随机的,提供更好的安全属性)。 RSA PKCS#1 v1.5签名生成和PSS签名生成在RFC 3447 (也称为RSA v2.1规范)中定义。

如果你使用你的代码和RSA 512位(仅用于testing目的,使用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----- 

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

 YY6sur9gkHXH23cUbDMYjCJYqDdBK8GKp4XyRNl8H09cW8H/gKQI9Z6dkLMhNh7oPq1yABCRfTP8yRtfLVj7FA== 

和hex

 618eacbabf609075c7db77146c33188c2258a837412bc18aa785f244d97c1f4f5c5bc1ff80a408f59e9d90b321361ee83ead720010917d33fcc91b5f2d58fb14 

使用RAW RSA进行解密(即,使用公开指数的模幂运算):

 0001ffffffffffffffffffff003031300d0609608648016503040201050004202af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64 

这是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 

所以那最后是哈希,在这种情况下,只是Test 123\n因为我不想今天input任何XML。

 $ sha256sum some_document.xml 2af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64 some_document.xml $ sha256sum some_document.xml 2af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64 some_document.xml