web-dev-qa-db-ja.com

node.jsを使用してCA証明書でX509証明書を検証する

私に与えられたCA証明書を使用して、X509形式のクライアント証明書を検証するnode.jsの方法を探しています(それらのどれも私が作成/管理していないため、私のソフトウェアは、送信されたものを検証するだけで済みます) 。

この仕事のためにいくつかのモジュールを見つけましたが、それぞれに問題があります。

  • X509x509.verify(cert, CABundlePath, cb)を使用してそれを行うことができますが、FSから証明書を読み取る必要があり、私はすでにメモリにそれらを持っています。これは、私のアプリに到達する各Webリクエストで行われるため、面倒です。
  • PKI.js はそれを行うことができるようですが、それらの例は私にとっては機能しませんが、ファイルの不足について不平を言うので、試すこともできません。
  • 私は node-forge を試しましたが、それを正しく使用しているかどうかはわかりませんが(APIドキュメントがないため)、forge.pki.verifyCertificateChain(caStore, [ cer ], cb)から_forge.pki.BadCertificate_エラーがスローされます。
  • pem を試行するときに、単純なpem.verifySigningChain(cer, [ ca ], cb)を使用すると、_/var/..._からのファイルのロードについてエラーが発生します。それが機能する場合でも、このlibをopensslコマンドラインツールに依存するものとして使用しないようにします。

上記のモジュールのいずれかを使用してこの単純なタスクを実行できなかったので、今はかなり愚かです。特定のCA証明書を使用してX509証明書の署名/有効性を確認できる簡単なソリューションを誰かに教えてもらえますか? :s

[編集]基本的には_openssl verify -verbose -CAfile ca-crt.pem client1-crt.pem_で_Node.js_が必要ですが、なし opensslコマンドラインツールへの依存関係とwithout証明書を一時的にディスクに保存します。

[編集2] https://nodejs.org/api/crypto.html#crypto_verify_verify_object_signature_signatureformat を使用することは可能ですか?

13
user826955

ようやくnode-forgeを使用してそれを行うことができました。実用的なコード例を次に示します。

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 + ')'));
}

両方の証明書は、base64でエンコードされたPEM形式/ js文字列で提供されます。

verifyCertificateChainは、証明書の有効性(notBefore/notAfter)をチェックし、指定されたCAチェーンを検証します。

verifyCertificateChainのソースコードは#TODOsでいっぱいであるため、これが最善の方法であるか、このライブラリが適切に機能しているかは100%わかりません。製造?しかし、少なくとも私は多少は有効な解決策を持っています。おそらく、libssl c呼び出しをラップするノードモジュールを作成する方が良いでしょうが、これはこの小さなタスクのための多大な労力です。

5
user826955

Httpリクエストから直接クライアント証明書を使用して確認したい場合は、次のようにすることもできます。

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

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))
    }
  }

requestからクライアントの「der」証明書を検証するより良い方法を見つけられませんでした。

fas3r

0
fas3r

これは私にとってはうまくいきます:

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)
}

.verifyが(falseを返すのではなく)エラーをスローしたため、try/catchが必要でした。

0
Joerg Veigel