如何在 Java 中使用 pin/password 加载 Windows-MY 密钥库?
How to load Windows-MY keystore with pin/password in Java?
我正在开发 java applet,它应该能够从 Windows-MY 实例读取证书。这是我能够做到并且工作正常的部分。我的问题是当我输入 PIN 码(通过编辑文本控件提供)时,Windows 证书管理器之后再次询问我相同的 PIN 码。
所以,我没有什么问题,如果你能帮助我,我将不胜感激。
- 我的代码哪里做错了,为什么它不使用我通过
EditText
控件提供的 PIN?如何做到这一点?
- 如果这不可能,请告诉我,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 applet,它应该能够从 Windows-MY 实例读取证书。这是我能够做到并且工作正常的部分。我的问题是当我输入 PIN 码(通过编辑文本控件提供)时,Windows 证书管理器之后再次询问我相同的 PIN 码。
所以,我没有什么问题,如果你能帮助我,我将不胜感激。
- 我的代码哪里做错了,为什么它不使用我通过
EditText
控件提供的 PIN?如何做到这一点? - 如果这不可能,请告诉我,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();
希望对您有所帮助。