5

組み込みのjettyサーバーとクライアント間のクライアント証明書認証に取り組んでいます。どちらもキーストアを使用します。クライアント証明書は、CA によって署名されたサーバーの証明書によって署名されます。Jetty は 2 つの方法を使用して、クライアント証明書 javax.net.ssl.SSLEngine を認証します。これは動作しているようで、上記のコードも使用します。

List<X509Certificate> certList = Certificate chain sent by the client
KeyStore truststore = server's truststore

//No use of CRL/OSCP/CRLDP
_crls = null;
_enableOCSP = false;
_enableCRLDP = false;

try{
 X509CertSelector certSelect = new X509CertSelector();
 certSelect.setCertificate((X509Certificate) certList.get(0));

 // Configure certification path builder parameters
 PKIXBuilderParameters pbParams = new PKIXBuilderParameters(truststore, certSelect);
 pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)));

 // Set maximum certification path length
 pbParams.setMaxPathLength(-1);

 // Enable revocation checking
 pbParams.setRevocationEnabled(true);

 // Set static Certificate Revocation List
 if (_crls != null && !_crls.isEmpty())
     pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls)));

  // Enable On-Line Certificate Status Protocol (OCSP) support
  if (_enableOCSP)
      Security.setProperty("ocsp.enable","true");

  // Enable Certificate Revocation List Distribution Points (CRLDP) support
  if (_enableCRLDP)
      System.setProperty("com.sun.security.enableCRLDP","true");

 // Build certification path
 CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams);               

 // Validate certification path
 CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams);
}catch(GeneralSecurityException gse){
 ...
}

もちろん、この 2 番目の方法を使用する必要があります... では、このコードに集中しましょう。これは、署名付き証明書を検証する良い方法ですか? ここに私のキーストアのダンプがあります:

クライアントキーストア:

Entry type: PrivateKeyEntry 
Certificate chain length: 2
Certificate[1]: 
Owner: EMAILADDRESS=truc@ok.com, CN=Servlet, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR 
Issuer: EMAILADDRESS=contact@greenpacs.com, CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR 
...

Certificate[2]: 
Owner: EMAILADDRESS=contact@greenpacs.com, CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR
Issuer: EMAILADDRESS=ghetolay@imbasoft.com, CN=Greenpacs Certificate Authority, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR 
...

サーバーのトラストストア:

Entry type: trustedCertEntry

Owner: EMAILADDRESS=contact@greenpacs.com, CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR
Issuer: EMAILADDRESS=ghetolay@imbasoft.com, CN=Greenpacs Certificate Authority, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR

これらのキーストアについてはよくわかりませんが、別のものを試してみました (CA 証明書をクライアントの証明書チェーンに追加し、証明書をトラストストアに追加)、検証はまだ失敗します。そして、これらのキーストアを使用すると、検証の最初の方法 (SSLEngine) が機能するようです。

デバッグ出力は大きすぎてここに記載できませんが、スタックトレースは次のとおりです。

java.security.cert.CertPathValidatorException: Could not determine revocation status
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:153)
    at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:325)
    at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:187)
    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:267)
    at MainClass.main(MainClass.java:75)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:197)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
    at sun.security.provider.certpath.CrlRevocationChecker.buildToNewKey(CrlRevocationChecker.java:583)
    at sun.security.provider.certpath.CrlRevocationChecker.verifyWithSeparateSigningKey(CrlRevocationChecker.java:459)
    at sun.security.provider.certpath.CrlRevocationChecker.verifyRevocationStatus(CrlRevocationChecker.java:339)
    at sun.security.provider.certpath.CrlRevocationChecker.verifyRevocationStatus(CrlRevocationChecker.java:248)
    at sun.security.provider.certpath.CrlRevocationChecker.check(CrlRevocationChecker.java:189)
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:131)
    ... 4 more

失効を無効にするか、(最初の証明書ではなく) 最後の証明書を X509CertSelector として設定すると、コードは機能しますが、何をしているのかわかりません。

jetty コードについて疑い始めていますが、私は証明書と SSL ハンドシェークの専門家ではないため、不適切なキーストア/トラストストアから発生する可能性もあります。そのため、私は jetty のボードでイシューを作成せず、コードを変更する必要があることを確認するために、以前にここで質問しました。

また、Java で署名された証明書を検証する方法を知っておくと役立つ場合があります。

4

2 に答える 2

0

実際、自分で検証を行う必要はありません。

SSLEngineすでにそれを行っています。有効な証明書がクライアントから送信された場合は、次を使用して取得できます。getPeerCertificateChain()証明書がない場合、またはクライアントから無効な証明書が送信された場合getPeerCertificateChain()は、例外がスローされます。

Jetty (または私が推測する任意の Java ServletContainer) を使用して、HttpServletRequest の属性 ["javax.servlet.request.X509Certificate"] をチェックして、有効な証明書がクライアントから送信されたかどうかを確認するだけです。

Javaで証明書を検証する方法はまだわかりませんが、このソリューションで十分です:)もう自分で行う必要はありません。ブルーノに感謝!

于 2012-09-17T13:25:32.960 に答える
-1

証明書の CRL または OCSP がアクセス可能であることを確認してください。そのような情報は、次のような証明書で確認できます。

[1]CRL Distribution Point
     Distribution Point Name:
          Full Name:
               URL=http://crl.verisign.com/pca2-g2.crl
于 2012-09-17T09:24:48.180 に答える