使用node.js验证具有CA证书的{x 449}证书

时间:2018-01-22 08:53:54

标签: node.js ssl certificate verification ca

我正在寻找一种node.js方法来验证X509格式的客户端证书以及给我的CA证书(这些证书都不是由我创建/管理的,我的软件只需要验证发送的是什么它)。

我找到了这个工作的几个模块,但是每个模块都有问题:

  • X509能够使用x509.verify(cert, CABundlePath, cb)执行此操作,但是它需要从FS读取证书,并且我已经在内存中使用它们了。这很麻烦,因为每个Web请求都会到达我的应用程序。
  • 似乎PKI.js能够做到这一点,但是他们的例子对我不起作用,但抱怨丢失的文件,所以我甚至无法尝试。
  • 我尝试了node-forge,但我不确定我是否正确使用它(它们没有任何API文档),它会从forge.pki.BadCertificate中抛出forge.pki.verifyCertificateChain(caStore, [ cer ], cb)错误。< / LI>
  • 尝试pem时,使用简单的pem.verifySigningChain(cer, [ ca ], cb)会引发一些错误,抱怨从/var/...加载文件。即使它可以工作,我也会避免使用这个lib作为依赖 openssl命令行工具,我想避免使用

现在我觉得非常愚蠢,因为我没有完成上述任何模块的简单任务。有人能指出一个简单的解决方案,这将允许我使用给定的CA证书验证X509证书的签名/有效性吗? :■

[edit]基本上我需要openssl verify -verbose -CAfile ca-crt.pem client1-crt.pem中的Node.js,但 没有 依赖于openssl命令行工具和 暂时将证书保存到磁盘。

[edit2]是否可以使用https://nodejs.org/api/crypto.html#crypto_verify_verify_object_signature_signatureformat

3 个答案:

答案 0 :(得分:4)

我终于设法使用node-forge。下面是一个有效的代码示例:

let pki = require('node-forge').pki;

let caCert;
let caStore;

try {
    caCert = fs.readFileSync('path/to/ca-cert.pem').toString();
    caStore = pki.createCaStore([ caCert ]);
} catch (e) {
    log.error('Failed to load CA certificate (' + e + ')');
    return....;
}

try {
    pki.verifyCertificateChain(caStore, [ cert ]);
} catch (e) {
    return handleResponse(new Error('Failed to verify certificate (' + e.message || e + ')'));
}

两个证书都应以base64编码的PEM格式/ js字符串给出。

verifyCertificateChain检查证书有效性(notBefore / notAfter)以及验证给定的CA链。

我不是百分之百确定这是否是最好的方法,或者这个库是否做得很好,因为它们的源代码verifyCertificateChain已经满了#TODO s,所以这可能是还没准备好生产? 但至少我有一个有点工作的解决方案。可能最好创建一个包装libssl c调用的节点模块,但这只是为这个小任务付出了很多努力。

答案 1 :(得分:0)

这对我有用:

const fs = require('fs'), pki = require('node-forge').pki
var ca = pki.certificateFromPem(fs.readFileSync('ca.pem', 'ascii'))
var client = pki.certificateFromPem(fs.readFileSync('client.pem', 'ascii'))
try {
    if (!ca.verify(client)) throw 'verify failed'
} catch (err) {
    console.log(err)
}

需要try / catch,因为在我的情况下.verify引发了错误(而不是返回false)。

答案 2 :(得分:-1)

如果您想直接从http请求中检查使用客户端证书,也可以这样做:

// retrieve certificates from the request ( in der format )
clientCert = req.connection.getPeerCertificate(true).raw.toString('base64'))

将der证书转换为pem并针对蓖麻进行验证的方法。

  const caCert = fs....
  const ca = pki.certificateFromPem(caCert)
  const caStore = pki.createCaStore([ ca ])

  const verify = (clientCert, next) => {
    try {
      const derKey = forge.util.decode64(clientCert)
      const asnObj = forge.asn1.fromDer(derKey)
      const asn1Cert = pki.certificateFromAsn1(asnObj)
      const pemCert = pki.certificateToPem(asn1Cert)
      const client = pki.certificateFromPem(pemCert)
      return pki.verifyCertificateChain(caStore, [ client ], cb)
    } catch (err) {
      next(new Error(err))
    }
  }

我没有找到更好的方法来验证来自request的客户端“ der”证书。

fas3r