2011-02-15 2 views
2

서버 (PHP, JSP)에서 스크립트를 호출해야합니다. 그러나이 서버는 클라이언트 인증에 의해 보호됩니다. 이제는 P12-Keystore로이 작업을 수행 할 수 있습니다. 이에 대한 코드 :PKCS11 토큰 (스마트 카드)을 사용하여 클라이언트 인증 수행

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) 

는 문제를 참조 바랍니다. 사전에 감사합니다 ... 다니엘

+0

alg을 요청하면 안됩니다. "SunX509"는 HW 제공자에게만 제공되며, 이는 소프트웨어 전용입니다 (그리고 certs의 공개 키만 처리하므로 괜찮습니다). 아마도 null로 init kmf를하지 말아야한다. 아마도 키 스토어 iks로 init과 init을 시도 할 것이다. 이 문제가 해결 되었습니까? 답변을 게시 할 수 있습니까? –

답변

1
Builder builder = Builder.newInstance("PKCS11", provider, new KeyStore.CallbackHandlerProtection(/*PIN callback handler instance*/)); 
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); 
kmf.init(new KeyStoreBuilderParameters(builder)); 

이 잘 작동합니다.