2011-02-15 118 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」給硬件提供商,這只是軟件(它只處理證書中的公鑰,所以沒問題)。你可能不應該使用null初始化kmf,我猜試着用keystore iks初始化它。此問題是否已解決?你能發表一個答案嗎? – 2011-05-19 12:24:16

回答

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

這應該工作正常。

相關問題