0

Tomcatサーバー(Linux上)がclient-authentication = on(org.jboss.web.connector.ssl.client-auth = true)で実行されている場合、クライアント(OSX 1.7.3)はJNLPを(ブラウザーで)ダウンロードできます。 )が、java-webstartはJNLPでさえもダウンロードできず、空の証明書選択ダイアログのみが表示されます。

証明書は自己署名のものです。CAとクライアントの証明書はOSXのKeyChainにインポートされます(ca-> system、client + key-> login)

問題をデバッグすると、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"));
}

}
4

1 に答える 1

0

これで問題が解決するかどうかはわかりませんが、次の点に注意してください。

  • KeychainStore、任意のパスワードで機能するように設計されています。

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

    (ある程度、Javaとの対話なしで、PINコードを入力することを期待するキーパッドを備えたハードウェアトークンに似ています。)

  • キーチェーンに複数のID(証明書+対応する秘密鍵)がある場合、とにかく1つしか見ることができないというバグがありましたKeychainStore。(前回チェックしたところ、これは修正されていませんでした。)

  • Safariには、クライアント証明書の選択に関して多くの問題がありました(選択が常に提供されるとは限らず、事前にID構成を手動で行う必要がありました。または、サーバーがクライアント証明書なしで接続を拒否した場合にのみ実行されます。ApacheHttpd's SSLVerifyClient optionalwilln動作しません)。これらの問題が修正されたかどうかはわかりません。

  • 自己署名クライアント証明書を使用している場合は、承認済みの発行者としてアドバタイズするようにTomcatを構成するか、空のリストを送信する必要があります。後者はTLS1.1によって明示的に承認されていますが、OSXがクライアント側でどのように動作するかはわかりません。

于 2012-04-16T17:50:45.363 に答える