Node.js verify.verify()奇怪的行为

时间:2018-09-28 17:39:47

标签: node.js cryptography digital-signature

我一直在开发数字签名的node.js应用程序,然后我遇到无法解决的奇怪行为。

首先,我生成的公用/专用密钥对为described here

然后我实现了以下脚本

  const crypto = require('crypto');
  const fs = require('fs');
  const privateKey = fs.readFileSync('./private_key.pem');
  const publicKey = fs.readFileSync('./public_key.pem');
  const hashAlg = 'sha256'
  const data = Buffer.from('test signature'.repeat(100), 'utf8');

  let bytes = []
  // sign
  const sign = crypto.createSign(hashAlg);
  sign.update(data);
  const signature = sign.sign(privateKey);
  fs.writeFileSync(`./signature.${hashAlg}`, publicKey);
  const verifier = crypto.createVerify(hashAlg);
  verifier.update(data);
  const result = verifier.verify(publicKey, signature);
  for(let i=0; i < publicKey.length ; i++){
    try{
      const verifier2 = crypto.createVerify('RSA-SHA256');
      verifier2.update(data);
      const invalidPublicKey = Buffer.from(publicKey);
      invalidPublicKey[i] = invalidPublicKey[i]+1;
      const result2 = verifier2.verify(invalidPublicKey, signature);
      if(result2) {
        bytes.push(i);
      };
    } catch (e) {
      // error to be handled
    }
  }
  if(bytes.length){
    console.log('****************');
    console.log(`key length: ${publicKey.length}`); // 451
    console.log('Bytes to be changed, and the verify would be valid');
    console.log(bytes.join(',')); // 49, 450
    console.log('****************');
  }

不同的公钥如何验证签名,我在这里缺少什么吗?

1 个答案:

答案 0 :(得分:2)

因此,假设您显然在Unix上使用了RSA-2048密钥对中的OpenSSL git status

  • PEM文件中偏移量49处的字符对偏移量16和17处的字节的一部分进行编码(特别是偏移量16的后4位和偏移量17的前2位)。这些是2字节的NULL,代表X.509 SubjectPublicKeyInfo格式的AlgorithmIdentifier的参数部分。对于RSA,没有算法参数(这就是为什么编码使用NULL的原因),尽管仍应对该字段进行解码,也许nodejs不会这么做,因为它知道不需要并会被忽略。

  • PEM文件中偏移量450处的字符是换行符,用于终止页脚行。尽管格式定义要求这样做,但实际上并不需要解析它来提取文件的内容,即公钥blob,而nodejs则不需要。