[英]Using node.js to verify a X509 certificate with CA cert
I am looking for a node.js way to verify a client certificate in X509 format with a CA certificate which was given to me (none of those are created/managed by me, my software only has to verify what is beeing sent to it). 我正在寻找一种node.js方法来验证X509格式的客户端证书以及给我的CA证书(这些证书都不是由我创建/管理的,我的软件只需要验证发送给它的内容) 。
I have found several modules for this job, however I am having issues with each of them: 我已经为这项工作找到了几个模块,但是每个模块都有问题:
x509.verify(cert, CABundlePath, cb)
, however it needs to read the certificates from FS, and I am having them in memory already. x509.verify(cert, CABundlePath, cb)
来完成它,但是它需要从FS读取证书,而我已经在内存中使用它们了。 This is cumbersome as it will be done with each web request which reaches my app. forge.pki.BadCertificate
error from forge.pki.verifyCertificateChain(caStore, [ cer ], cb)
. forge.pki.verifyCertificateChain(caStore, [ cer ], cb)
抛出一个forge.pki.BadCertificate
错误。 pem.verifySigningChain(cer, [ ca ], cb)
would throw some error complaining about loading a file from /var/...
. pem.verifySigningChain(cer, [ ca ], cb)
会引发一些错误,抱怨从/var/...
加载文件。 Even if it would work, I would avoid using this lib as its relying on the openssl command line tool , which I would like to avoid Now I feel pretty stupid because I failed to get this simple task done with any of the above modules. 现在我感觉非常愚蠢,因为我没有完成上述任何模块的简单任务。 Could someone point me to a simple solution which will allow me to verify the signature/validity of a X509 certificate using a given CA certificate?
有人能指出一个简单的解决方案,这将允许我使用给定的CA证书验证X509证书的签名/有效性吗? :s
:■
[edit] Basically I would need openssl verify -verbose -CAfile ca-crt.pem client1-crt.pem
in Node.js
but without dependencies to the openssl command line tool and without temporarily saving the certs to disk. [编辑]基本上我需要在
Node.js
openssl verify -verbose -CAfile ca-crt.pem client1-crt.pem
,但不依赖于openssl命令行工具, 也不需要暂时将证书保存到磁盘。
[edit2] Would it be possible to just use https://nodejs.org/api/crypto.html#crypto_verify_verify_object_signature_signatureformat ? [edit2]是否可以使用https://nodejs.org/api/crypto.html#crypto_verify_verify_object_signature_signatureformat ?
I finally managed to do it using node-forge
. 我终于设法使用
node-forge
来做到这一点。 Heres a working code example: 下面是一个有效的代码示例:
let pki = require('node-forge').pki;
let fs = require('fs');
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 + ')'));
}
Both certificates shall be given in base64 encoded PEM format/js string. 两个证书都应以base64编码的PEM格式/ js字符串给出。
verifyCertificateChain
checks the certifitate validity ( notBefore
/ notAfter
) as well as verifies the given CA chain. verifyCertificateChain
检查证书有效性( notBefore
/ notAfter
)以及验证给定的CA链。
I am not 100% sure if this is the best approach, or if this library is doing a good job, since their source code of verifyCertificateChain
is full of #TODO
s, so maybe this is not ready for production? 我不是100%确定这是否是最好的方法,或者这个库是否做得很好,因为他们的
verifyCertificateChain
的源代码充满了#TODO
,所以也许这还没有准备好生产? But at least I have a somewhat working solution. 但至少我有一个有点工作的解决方案。 Probably it would be better to create a node module which wraps the
libssl
c calls, but thats just a lot of effort for this small task. 可能最好创建一个包装
libssl
c调用的节点模块,但这只是为这个小任务付出了很多努力。
This works for me: 这对我有用:
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 was required, because .verify threw an error (instead of returning false) in my case. try / catch是必需的,因为.verify在我的情况下抛出了一个错误(而不是返回false)。
You can also do like this if you want to check the using the client certificates from the http request directly : 如果要直接使用http请求中的客户端证书检查,也可以这样做:
// retrieve certificates from the request ( in der format )
clientCert = req.connection.getPeerCertificate(true).raw.toString('base64'))
Method to convert the der certificate to pem and verify against the castore. 将der证书转换为pem并针对castore进行验证的方法。
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))
}
}
I did not find a better way to verify the client "der" certificate from the request
. 我没有找到更好的方法来验证
request
的客户端“der”证书。
fas3r fas3r
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.