2012-04-16 9 views
0

Tomcatサーバー(Linuxの場合)がclient-authentication = on(org.jboss.web.connector.ssl.client-auth = true)で実行されている場合、クライアント(OSX 1.7.3)はJNLP(ブラウザ内)をダウンロードできますが、java-webstartはJNLP以外のものをダウンロードすることはできません。OSX JNLPのダウンロードがKeyChainの証明書に届かない

証明書は、自己署名ものです。 CA証明書とクライアント証明書がOSXのキーチェーンにインポートされます(ca->システム、クライアント+キー - >ログイン)

問題をデバッグすると、AppleのJNLP JavaインターフェイスがOSXのKeyChainキーストアに間違った方法、パスワードなし(*下記の例を参照)

JNLPダウンロード(OSX上)で実行中のコードのデバッグに基づいて小さなプログラムを作成しました。これはここにあなたの問題を解決しますが、場合

import java.security.Key; 
import java.security.KeyStore; 
import java.security.cert.Certificate; 
import java.security.cert.X509Certificate; 
import java.util.Enumeration; 

import javax.net.ssl.KeyManager; 
import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.X509KeyManager; 

public class OSXKeyChainTest { 

/** 
* Demonstrating issue in OSX-JNLP-Java interface, the keys from the 
* KeyChain are not accessed during JNLP downloading phase. But if it would 
* use any password it would work (see the FIXME line). This small test 
* program is based on the debugging works on OSX 1.7.3. 
*/ 
public static void main(String[] args) throws Exception { 

    KeyStore ks = KeyStore.getInstance("KeyChainStore", "Apple"); 
    ks.load(null, new char[0]); 
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509", "SunJSSE"); 

    // FIXME !!!! try it with ANY password, and it will work, eg. = new char[] {'x'}; 
    char[] password = new char[] {}; 

    // as AppleX509DeployKeyManager.getBrowserKeyManager() does 
    keyManagerFactory.init(ks, password); 

    X509KeyManager localX509KeyManager = null; 
    KeyManager[] arrayOfKeyManager = keyManagerFactory.getKeyManagers(); 

    int i = 0; 
    while (i < arrayOfKeyManager.length) { 
     if ((arrayOfKeyManager[i] instanceof X509KeyManager)) { 
      localX509KeyManager = (X509KeyManager) arrayOfKeyManager[i]; 
      break; 
     } 

     i++; 
    } 

    for (Enumeration<String> t = ks.aliases(); t.hasMoreElements();) { 
     String alias = t.nextElement(); 
     System.out.println("@Alias: " + alias); 
     if (ks.isKeyEntry(alias)) { 
      System.out.println("It's a key entry"); 
      for (Certificate c : ks.getCertificateChain(alias)) { 
       X509Certificate x509 = (X509Certificate) c; 
       System.out.println(x509.getSubjectDN().toString()); 
       System.out.println("SN: " + x509.getSerialNumber()); 
      } 

      // as SunX509KeyManagerImpl does 
      Key localKey = ks.getKey(alias, password); 
      System.out.println("Localkey: " + localKey); 
     } 
    } 

    System.out.println("--------------------------------"); 
    System.out.println("It should be not null!: " + localX509KeyManager.getPrivateKey("client")); 
} 

} 

答えて

0

わからないいくつかのポイントは、あなたが見てする必要があります:

  • KeychainStoreは、任意のパスワードを使用して動作するように設計されています。

    実際の認可は、OSXのセキュリティデーモンで処理する必要があります。秘密鍵を使用しようとすると、ポップアップが表示され、「このアプリケーションがこの秘密鍵を使用して署名できるようにしますか?このようなプロンプトが表示されない場合は、プロンプトなしにキーを使用するアプリケーションを承認した可能性があります。設定はKeychain.appに変更できます。

    (度に、それは、Javaとの対話なし、あなたがPINコードを入力することを期待キーパッドとハードウェアトークンと同様である。)

  • あなたが複数のIDを持っている場合(CERT +対応秘密鍵)をthere was a bug whereby the KeychainStore could only see one anywayに置き換えてください。 (最後に確認したところ、これは修正されていませんでした)

  • Safariにはクライアント証明書の選択に関する多くの問題がありました。選択肢は常に提供されるとは限らず、事前に手動で設定する必要がありました。サーバーがクライアント証明書なしで接続を拒否した場合にのみ行われます。Apache HttpdのSSLVerifyClient optionalは機能しません)。これらの問題が修正されたかどうかはわかりません。

  • 自己署名入りのクライアント証明書を使用している場合は、受け入れた発行者として広告するようにTomcatを設定するか、空のリストを送信する必要があります。後者はTLS 1.1によって明示的に承認されていますが、OSXがクライアント側でどのように動作するかはわかりません。

関連する問題