java - 如何在 Java 中使用 pin/密码加载 Windows-MY keystore ?

标签 java applet x509certificate keystore digital-certificate

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

所以,我有几个问题,如果您能够帮助我,我将非常感激。

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

这是我的小程序中使用的部分代码:

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

愿意采用不同的方法来解决这个问题。

最佳答案

您需要实现一个回调处理程序 请查看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();

我希望这能有所帮助。

关于java - 如何在 Java 中使用 pin/密码加载 Windows-MY keystore ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38958622/

相关文章:

java - "java"中找到的 "jdk1.8.0_121/bin"文件与 "jdk1.8.0_121/jre/bin"中找到的文件有什么区别?

java - Hibernate 中层次结构的高效表示

java - 叶证书和子证书的用途是什么以及如何使用它们?

java - 使用 java 11 编译 cumulocity-clients-java 时出错

java - 当我启动 apk 文件时出现以下错误

java - 在我的小程序中使用 webrenderer 时出现错误

java - Java中使用一个TextField输入多个数据

java - 在JAVA中重新绘制Applet,而不丢失以前的内容

ssl - CA 签名的 X509 证书包含两次 X509v3 扩展 "Subject Alternative Name"

Java 为 CRL 路径设置默认值