2012-09-17 18 views
5

私は、埋め込みJettyサーバーとクライアントの間のクライアント証明書認証に取り組んでいます。どちらもキーストアを使用します。クライアント証明書は、CAによって署名されたサーバー証明書によって署名されます。 Jettyは、クライアント証明書javax.net.ssl.SSLEngineを認証するために2つのメソッドを使用します。これらのメソッドは動作しています。また、上記のコードも使用します。もちろんJava/Keystore署名付き証明書の確認

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

私は、それでは、このコードに集中しましょう。この第二の方法... を使用する必要があり、これは署名入りの証明書を検証するための良い方法ですか?ここで は私のキーストアのダンプです:

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

Entry type: PrivateKeyEntry 
Certificate chain length: 2 
Certificate[1]: 
Owner: [email protected], CN=Servlet, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR 
Issuer: [email protected], CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR 
... 

Certificate[2]: 
Owner: [email protected], CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR 
Issuer: [email protected], CN=Greenpacs Certificate Authority, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR 
... 

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

Entry type: trustedCertEntry 

Owner: [email protected], CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR 
Issuer: [email protected], 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のようなコードの作業を(代わりに、最初の)最後の証明書を設定した場合しかし、私は何をやっているのか分かりません。

私は桟橋のコードについて疑問を持ち始めていますが、私は証明書とSSLハンドシェイクの専門家ではないため、悪いキーストア/トラストストアから来る可能性もあります。だからこそ私は桟橋の掲示板に問題を作り出していないので、コードを変更する必要があることをここで尋ねました。

また、Javaで署名付き証明書を検証する方法を知っておくと便利です。

+0

JSSE経由でトラストマネージャーにあなたのためにすべてをさせてみませんか? – Bruno

+0

私のサーバも非cert-auth接続を受け入れています。私はまずそれがすべての接続を受け入れるようにしなければならないし、場合によってはクライアントの証明書があればそれを検証する必要があります。 – Ghetolay

+4

いいえ、(必要ではなく)wantClientAuthオプションを使用してクライアント証明書をオプションにする必要があります。 – Bruno

答えて

0

証明書のCRLを確認するかOCSPはアクセス可能であり、あなたは、このような

[1]CRL Distribution Point 
    Distribution Point Name: 
      Full Name: 
       URL=http://crl.verisign.com/pca2-g2.crl 
+0

私はCRL、OSCP、またはCRLDPを使用しません。証明書にそのような行はありません。また、表示されているコードは完全ではありませんが、CRL/OSCP/CRLDPの「if」がいくつかありますが、これらのオプションを設定していないためにこれらのifに到達することはありません。したほうがいい ?それは絶対に必要ですか? – Ghetolay

0

として、証明書にそのような情報を見つけることができます実際に私が検証を自分で行う必要はありませんしてください。

SSLEngineのは、すでにそれをやっているし、有効な証明書がクライアントによって送信された場合に証明書または無効な証明書がgetPeerCertificateChain()リターンヌルスロークライアントによって送信されない場合は、それがgetPeerCertificateChain()を使用して取得することができます例外。

jetty(またはJava ServletContainerと思われる)を使用すると、HttpServletRequestの属性["javax.servlet.request.X509Certificate"]をチェックして、有効な証明書がクライアントによって送信されたかどうかを確認するだけで済みます。

Javaで証明書を検証する方法はまだ分かりませんが、このソリューションでは十分です。私はもうそれ以上は必要ありません。ブルーノのおかげで!

+0

getPeerCertificateChain()はnullを戻さず、例外をスローします。 – EJP

関連する問題