如何在Java中使用pin / password加载Windows-MY密钥库?

时间:2016-08-15 16:02:49

标签: java applet x509certificate keystore digital-certificate

我正在开发java applet,它应该能够从Windows-MY实例中读取证书。这是我能够做的部分并且工作正常。我的问题是当我输入PIN码(通过编辑文本控件提供)时,Windows证书管理员再次要求我输入相同的PIN码。

所以,我几乎没有问题,如果你能帮助我,我将非常感激。

  1. 我的代码中出错了什么,为什么它没有使用我通过EditText控件提供的PIN?怎么做到这一点?
  2. 如果无法做到,请告诉我,PKCS#12数字证书的行为方式与PKCS#11智能卡证书相同吗?确切地说,他们是否像PKCS#11一样要求PIN?如果是这样,我应该能够删除我的PIN字段并让Windows完成这部分工作。
  3. 以下是我的applet中使用的代码的一部分:

    keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
    keystore.load(null,_PIN);
    
    String aliass = (String) aliasses.nextElement();
    X509Certificate oPublicCertificate = (X509Certificate) keystore.getCertificate(alias);
    PrivateKey oPrivateKey = (PrivateKey) keystore.getKey(alias,null);
    if(oPrivateKey == null) continue;
    if(aliass != alias) continue;
    
    System.out.println("Sign with alias:"+aliass);
    System.out.println("gettype:"+oPublicCertificate.getType());
    System.out.println("serial:"+oPublicCertificate.getSerialNumber());
    System.out.println("Public Key:"+oPublicCertificate.getPublicKey());
     _PK = Base64Utils.base64Encode(oPublicCertificate.getPublicKey().getEncoded());
    System.out.println("Public Key:"+_PK);
    
    Provider p = keystore.getProvider();
    // data to sign
    byte[] data ="Data for signing".getBytes();
    // Signing the data
    Signature sig = Signature.getInstance("SHA1withRSA");
    sig.initSign(oPrivateKey);
    
    sig.update(data);
    
    byte[] signature = sig.sign();  //<--- Here asks for PIN second time.
    
    System.out.println("Signature.sign():" + signature);
    
    Signature verifier = Signature.getInstance("SHA1withRSA", p);
    verifier.initVerify(oPublicCertificate);
    verifier.update(data);
    boolean isValidSignature = verifier.verify(signature);
    System.out.println("the verification result "+ isValidSignature);
    

    打开了解决此问题的不同方法。

1 个答案:

答案 0 :(得分:1)

您需要实现一个回调处理程序 请查看this

这个例子从上面提到的引用中复制,它覆盖了回调处理

public void handle(Callback[] callbacks)
 throws IOException, UnsupportedCallbackException {

   for (int i = 0; i < callbacks.length; i++) {
      if (callbacks[i] instanceof PasswordCallback) {

          // prompt the user for sensitive information
          PasswordCallback pc = (PasswordCallback)callbacks[i];
          System.err.print(pc.getPrompt());
          System.err.flush();
          pc.setPassword(readPassword(System.in));

      } 
   }
 }

然后你可以使用你的回调

CallbackHandler callBackHandler = new yourImplementedHandler();
KeyStore.ProtectionParameter protection = new KeyStore.CallbackHandlerProtection(callBackHandler);
Provider provider = Security.getProvider("SunMSCAPI");
KeyStore.Builder keystoreBuilder = KeyStore.Builder.newInstance("Windows-MY",
                                                                provider, 
                                                                protection);
KeyStore keystore = keystoreBuilder.getKeyStore();

我希望这可以提供帮助。