使用 sunpkcs#11 和 tomcat 移除和插入智能卡 [英] remove and insert smartcard using sunpkcs#11 and tomcat

查看:60
本文介绍了使用 sunpkcs#11 和 tomcat 移除和插入智能卡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在 Tomcat 上运行的 Web 应用程序.我的应用程序使用一个网络服务,该服务通过智能卡进行签名并发送电子邮件.Web 服务本身会在第一次通话期间和发送电子邮件之前自动添加 sunpkcs#11 提供程序,然后如果 智能卡 未被移除和插入,则可以登录并发送电子邮件.如果删除并插入,为了发送电子邮件,我必须重新启动 tomcat 服务器,否则它会根据我的代码给出几个错误:

result= api.signAndSend(to, cc, bcc, subject, content, smartCardPin);

取出并插入智能卡后,此代码给出以下异常消息:

<块引用>

令牌已被移除

这些是我的尝试:

  1. 在发送电子邮件并创建新的 sunpkcs#11 提供程序并添加它之后,我尝试删除 sunpkcs#11 提供程序.它给出如下错误:

<块引用>

java.security.InvalidKeyException: 没有安装的提供程序支持这个密钥:sun.security.pkcs11.P11Key$P11PrivateKey 或java.security.InvalidKeyException: 没有安装的提供程序支持这个键:空

  1. 我没有在每次 api.signAndSend(...) 调用后删除 sunpkcs#11 提供程序,

而是:

 result= api.signAndSend(to, cc, bcc, subject, content, smartCardPin);SunPKCS11 sunPKCS11=(SunPKCS11)getLastProvider();sunPKCS11.logout();sunPKCS11.setCallbackHandler(new MyCallbackHandler());KeyStore.CallbackHandlerProtection cpprotection = new KeyStore.CallbackHandlerProtection(新的 MyCallbackHandler());KeyStore.Builder 构建器 = KeyStore.Builder.newInstance("PKCS11", sunPKCS11, cpprotection);KeyStore ks = builder.getKeyStore();//完成PKCS#11Field moduleMapField = PKCS11.class.getDeclaredField("moduleMap");moduleMapField.setAccessible(true);映射moduleMap = (Map) moduleMapField.get(null);moduleMap.clear();//下次强制重新执行 C_Initialize//加载 PKCS#11(我希望此代码再次加载 pkcs#11 但我不确定)Method getInstanceMethod = PKCS11.class.getMethod("getInstance",String.class, String.class, CK_C_INITIALIZE_ARGS.class,Boolean.TYPE);CK_C_INITIALIZE_ARGS ck_c_initialize_args = new CK_C_INITIALIZE_ARGS();PKCS11 pkcs11 = (PKCS11) getInstanceMethod.invoke(null, pkcs11Path,"C_GetFunctionList", ck_c_initialize_args, false);

此代码给出:

<块引用>

java.security.ProviderException:初始化失败在 sun.security.pkcs11.P11Signature.initialize(P11Signature.java:319)在 sun.security.pkcs11.P11Signature.engineInitSign(P11Signature.java:432)在 java.security.Signature$Delegate.init(Signature.java:1127)在 java.security.Signature$Delegate.chooseProvider(Signature.java:1087)在 java.security.Signature$Delegate.engineInitSign(Signature.java:1151)在 java.security.Signature.initSign(Signature.java:512)在 org.esign.bouncycastle.operator.jcajce.JcaContentSignerBuilder.build(来源不明)...引起:sun.security.pkcs11.wrapper.PKCS11Exception:CKR_KEY_HANDLE_INVALID在 sun.security.pkcs11.wrapper.PKCS11.C_SignInit(本机方法)在 sun.security.pkcs11.wrapper.PKCS11$SynchronizedPKCS11.C_SignInit(PKCS11.java:1721)在 sun.security.pkcs11.P11Signature.initialize(P11Signature.java:311)

java: 1.8.0.31

我像这样删除并添加 SunPkcs#11:

//下面的代码在第一次调用后自动添加sunpkcss provider结果= api.signAndSend(to, cc, bcc, subject, content, smartCardPin);//在每次signAndSend之后我删除sunpkcs并添加一个新的字符串 sunpkcs11Name=getLastProvider().getName();Security.removeProvider(sunpkcs11Name);String cfg = MessageFormat.format("name = Starcos-SunPkcs11 library = c:/windows/system32/aetpkss1.dll slot = 52481");InputStream is=new ByteArrayInputStream(cfg.getBytes());SunPKCS11 newSunPkcs11Provider = new SunPKCS11(is);Security.addProvider(newSunPkcs11Provider);

在我添加一个新的 SunPkcs11 之后,api.signAndSend(...) 它给出:

<块引用>

java.security.InvalidKeyException:没有已安装的提供程序支持此密钥:>sun.security.pkcs11.P11Key$P11PrivateKey

这个异常不是因为没有 SunPkcs11,因为我在提供者列表中看到了我添加的 SunPkcs11.

解决方案

在这类问题中很难找到确切的解决方案,因为很难重现它,所以根据我的阅读 PKCS#11 已经涵盖了这个 根据其文档

<块引用>

这适用于将 PKCS#11 标记视为静态的应用程序密钥库.对于想要容纳 PKCS#11 令牌的应用程序更动态地,例如插入和取出智能卡,您可以使用新的 KeyStore.Builder 类.这是一个如何操作的示例使用回调处理程序为 PKCS#11 密钥库初始化构建器.

您已经提到删除和添加提供程序对您不起作用,但根据此post 他们通过这种方式解决了它.

I have a web application running on Tomcat. My application uses a web service which signs (via smartcard) and sends email. The web service itself adds the sunpkcs#11 provider automatically during the first call and before sending email, then can sign in and send emails if smartcard is not removed and inserted. If removed and inserted, in order to send email I must restart the tomcat server or it will give several errors depending on my code:

result= api.signAndSend(to, cc, bcc, subject, content, smartCardPin); 

After removing and inserting smart card this code gives below exception message:

Token has been removed

These are my tryings:

  1. I tried removing the sunpkcs#11 provider just after sending email and creating a new sunpkcs#11 provider and adding it.it gives and error like:

java.security.InvalidKeyException: No installed provider supports this key: sun.security.pkcs11.P11Key$P11PrivateKey or java.security.InvalidKeyException: No installed provider supports this key: null

  1. I did not remove sunpkcs#11 provider after each api.signAndSend(...) call,

rather :

  result= api.signAndSend(to, cc, bcc, subject, content, smartCardPin);  
  SunPKCS11 sunPKCS11=(SunPKCS11)getLastProvider();  
  sunPKCS11.logout();  
  sunPKCS11.setCallbackHandler(new MyCallbackHandler());  
  KeyStore.CallbackHandlerProtection cpprotection = new KeyStore.CallbackHandlerProtection(  
  new MyCallbackHandler());  
  KeyStore.Builder builder = KeyStore.Builder.newInstance(  
  "PKCS11", sunPKCS11, cpprotection);  
  KeyStore ks = builder.getKeyStore();  

//finalize PKCS#11  
Field moduleMapField = PKCS11.class.getDeclaredField("moduleMap");  
  moduleMapField.setAccessible(true);  
  Map<?, ?> moduleMap = (Map<?, ?>) moduleMapField.get(null);  
  moduleMap.clear(); // force re-execution of C_Initialize next time  

//load PKCS#11(i expect this code to load pkcs#11 again but i am not sure)  
Method getInstanceMethod = PKCS11.class.getMethod("getInstance",  
  String.class, String.class, CK_C_INITIALIZE_ARGS.class,  
  Boolean.TYPE);  
  CK_C_INITIALIZE_ARGS ck_c_initialize_args = new CK_C_INITIALIZE_ARGS();  
  PKCS11 pkcs11 = (PKCS11) getInstanceMethod.invoke(null, pkcs11Path,  
  "C_GetFunctionList", ck_c_initialize_args, false);  

this code gives:

java.security.ProviderException: Initialization failed at sun.security.pkcs11.P11Signature.initialize(P11Signature.java:319) at sun.security.pkcs11.P11Signature.engineInitSign(P11Signature.java:432) at java.security.Signature$Delegate.init(Signature.java:1127) at java.security.Signature$Delegate.chooseProvider(Signature.java:1087) at java.security.Signature$Delegate.engineInitSign(Signature.java:1151) at java.security.Signature.initSign(Signature.java:512) at org.esign.bouncycastle.operator.jcajce.JcaContentSignerBuilder.build(Unknown Source) . . . Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_HANDLE_INVALID at sun.security.pkcs11.wrapper.PKCS11.C_SignInit(Native Method) at sun.security.pkcs11.wrapper.PKCS11$SynchronizedPKCS11.C_SignInit(PKCS11.java:1721) at sun.security.pkcs11.P11Signature.initialize(P11Signature.java:311)

java: 1.8.0.31

edit: i remove and add SunPkcs#11 like this:

//the code below adds sunpkcss provider automatically after first call
result= api.signAndSend(to, cc, bcc, subject, content, smartCardPin);

//after each signAndSend i remove sunpkcs and add a new one
String sunpkcs11Name=getLastProvider().getName();
Security.removeProvider(sunpkcs11Name);

String cfg = MessageFormat.format(
                "name = Starcos-SunPkcs11  library = c:/windows/system32/aetpkss1.dll slot = 52481 ");
        InputStream is=new ByteArrayInputStream(cfg.getBytes());

SunPKCS11 newSunPkcs11Provider = new SunPKCS11(is);
Security.addProvider(newSunPkcs11Provider);

after i add a new SunPkcs11, while api.signAndSend(...) it gives:

java.security.InvalidKeyException: No installed provider supports this key: >sun.security.pkcs11.P11Key$P11PrivateKey

This exception is not because of absence of SunPkcs11 because i see the SunPkcs11 that i added, in the providers list.

解决方案

It is hard to find exact solution in this kind of problem because it is hard to reproduce it so according to my reading PKCS#11 is already cover this Smartcards being inserted and removed scenario according to its documentation,

This is fine for an application that treats PKCS#11 tokens as static keystores. For an application that wants to accommodate PKCS#11 tokens more dynamically, such as Smartcards being inserted and removed, you can use the new KeyStore.Builder class. Here is an example of how to initialize the builder for a PKCS#11 keystore with a callback handler.

You already mention that remove and add provider is not working for you but according to this post they solve it via this way.

这篇关于使用 sunpkcs#11 和 tomcat 移除和插入智能卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆