Выполните аутентификацию клиента с помощью токена PKCS11 (Smartcard) - PullRequest
3 голосов
/ 15 февраля 2011

Мне нужно вызвать скрипт на сервере (php, jsp - что угодно).Но этот сервер защищен аутентификацией клиента.Теперь я могу сделать это с P12-Keystore.Код для этого:

    private void installSSLContextP12() throws Exception {
    KeyStore tks = KeyStore.getInstance(KeyStore.getDefaultType());
    tks.load(new FileInputStream("/home/dan/Dokumente/Zertifikate/store"), "xxx".toCharArray());                   // load truststore

    KeyStore iks = KeyStore.getInstance("PKCS12");
    iks.load(new FileInputStream("/home/dan/Dokumente/Zertifikate/danmocz_zert.p12"), "yyy".toCharArray());     // load private keystore

    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());            // init truststore
    tmf.init(tks);

    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(iks, "yyy".toCharArray());                                                                                    // load priv. key's pw
    KeyManager[] kms = kmf.getKeyManagers();


    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);                                                          // trust/keystore
    SSLContext.setDefault(ctx);  //That is enough to authenticate at the server
}

Это прекрасно работает.

Но теперь у меня есть смарт-карта (PKCS11), и мне нужно пройти аутентификацию с этим.Я использую провайдера opensc-cryptocard, чтобы прочитать карту.пример кода для этого приведен здесь (см. строчные комментарии!):

private void installSSLContextPKCS11() throws Exception {
    PKCS11Provider provider = new PKCS11Provider("/usr/lib/opensc-pkcs11.so.BAK");
    Security.addProvider(provider);

    System.out.println("loading truststore");
    KeyStore tks = KeyStore.getInstance(KeyStore.getDefaultType());
    tks.load(new FileInputStream("/home/dan/Dokumente/Zertifikate/store"), "xxx".toCharArray());                   // load truststore

    System.out.println("loading keystore");
    KeyStore iks = KeyStore.getInstance("PKCS11", provider);  //works fine. he asks for a right pin - cancels when pin is wrong
    iks.load(null, "zzz".toCharArray());                                                                                                         // load private keystore

    System.out.println("init truststore");
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());            // init truststore
    tmf.init(tks);

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");  // here is the problem. It seems that the pin is ignored. and if i overgive the provider (like KeyStore.getInstance-Method)i get an NoSuchAlgorithmException (for stacktrace see below)
    kmf.init(null, "834950".toCharArray());  //The debugger shows in kmf.getKeyManagers()-Array no priv. Key or anything. It contains nothing but an empty hashmap (or something like this) with p12 it contains the priv. key and the certificate from the smart card

    System.out.println("setting sslcontext");
    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    SSLContext.setDefault(ctx);

    System.out.println("doing handshake");
    final SSLSocketFactory factory = ctx.getSocketFactory();
    final SSLSocket socket = (SSLSocket) factory.createSocket("download.uv.ruhr-uni-bochum.de", 443);
    socket.setUseClientMode(true);
    socket.startHandshake();   // here i try to do the handshake. it works with a p12-keystore... like ahead. with pkcs11 i get an SSLHandshakeException (Received fatal alert: handshake_failure)
    System.out.println("done");
}

Исключение NoSuchAlgorythmException:

Exception in thread "main" java.security.NoSuchAlgorithmException: no such algorithm: SunX509 for provider OpenSC-PKCS11
    at sun.security.jca.GetInstance.getService(GetInstance.java:100)
    at sun.security.jca.GetInstance.getInstance(GetInstance.java:218)
    at javax.net.ssl.KeyManagerFactory.getInstance(KeyManagerFactory.java:217)
    at clientauthtest.Main.installSSLContextPKCS11(Main.java:130)
    at clientauthtest.Main.main(Main.java:54)

Надеюсь, вы видите проблему.Заранее спасибо ... Даниэль

1 Ответ

1 голос
/ 31 мая 2012
Builder builder = Builder.newInstance("PKCS11", provider, new KeyStore.CallbackHandlerProtection(/*PIN callback handler instance*/));
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(new KeyStoreBuilderParameters(builder));

Это должно работать нормально.

...