使用 PKCS11 令牌(智能卡)进行客户端身份验证

发布于 2024-10-17 15:46:51 字数 4110 浏览 3 评论 0原文

我必须调用服务器上的脚本(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)

希望您看到问题。 预先感谢...丹尼尔

I have to call a script on a server (php, jsp - what ever). But this server is protected by a client authentication. Now it is possible for me to do it with a P12-Keystore. The code for this:

    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
}

This works fine.

But now i have a Smartcard(PKCS11) and i need to authenticate with this. I use the opensc-cryptocard provider to read the card. the sample code for this comes here (see line comments !):

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");
}

The 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)

Hope you see the problem.
Thanks in advance... daniel

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随波逐流 2024-10-24 15:46:51
Builder builder = Builder.newInstance("PKCS11", provider, new KeyStore.CallbackHandlerProtection(/*PIN callback handler instance*/));
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(new KeyStoreBuilderParameters(builder));

这应该可以正常工作。

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

This should work fine.

亣腦蒛氧 2024-10-24 15:46:51

PHP 有一个 PKCS11 扩展,可用于签名、验证、加密或解密您的数据。请参阅:https://github.com/gamringer/php-pkcs11

一些示例可在测试/文件夹。例如,请参阅: https://github.com/ gamringer/php-pkcs11/blob/master/tests/0340-oasis_C_Encrypt.phpt

它对你的jsp没有帮助,但正如你所说你也可以使用php,你应该尝试一下。

PHP has a PKCS11 extension that can be used to sign, verify, encrypt or decrypt your data. See: https://github.com/gamringer/php-pkcs11

Some examples are available into the tests/ folder. For example see : https://github.com/gamringer/php-pkcs11/blob/master/tests/0340-oasis_C_Encrypt.phpt

It won't help for your jsp, but as you stated that you can use php too, you should give a try.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文