我使用java 1.8,以下代码适用于许多USB pkcs11设备,但本周我发现了一个新的令牌模型,当我执行" keystorePkcs11.getKey(alias,pass);"我收到错误CKR_ATTRIBUTE_TYPE_INVALID。此令牌具有单个证书
这是我用来进行测试的完整代码源:
package pkcs11test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.KeyManagerFactory;
import sun.security.pkcs11.SunPKCS11;
import sun.security.pkcs11.wrapper.CK_TOKEN_INFO;
import sun.security.pkcs11.wrapper.PKCS11;
import sun.security.pkcs11.wrapper.PKCS11Exception;
public class PKCS11Test {
public static void main(String[] args) {
try {
char[] pass = "******".toCharArray(); // PIN of the token
String dllFile = "D:\\temp\\cryptoide_pkcs11.dll"; // DLL file used to acces the token
String configFile = "config.cfg"; // config file
PKCS11 p11 = PKCS11.getInstance(dllFile, "C_GetFunctionList", null, false);
long[] slots = p11.C_GetSlotList(true);
for (int j = 0; j < slots.length; j++) {
CK_TOKEN_INFO tokenInfo = p11.C_GetTokenInfo(slots[j]);
System.err.println("Token found at position "+j+
" label "+new String(tokenInfo.label).toUpperCase().trim()+
" model "+new String(tokenInfo.model).toUpperCase().trim()+
" manufacturerID "+new String(tokenInfo.manufacturerID).toUpperCase().trim()+
" utcTime "+new String(tokenInfo.utcTime).toUpperCase().trim()+
" serial "+new String(tokenInfo.serialNumber).toUpperCase().trim());
PrintStream out = new PrintStream(new FileOutputStream(configFile));
out.print("name=SmartCard\r\n"+"library="+dllFile+"\r\nslotListIndex="+slots[j]+"\r\n");
out.close();
SunPKCS11 tempProv = new sun.security.pkcs11.SunPKCS11(configFile);
KeyStore keystorePkcs11 = KeyStore.getInstance("pkcs11", tempProv);
keystorePkcs11.load(null, pass);
KeyManagerFactory kKeyManagerFactory = KeyManagerFactory.getInstance("sunx509");
//kKeyManagerFactory.init(keystorePkcs11, null);
Enumeration<String> enume = keystorePkcs11.aliases(); // read aliases from token
while(enume.hasMoreElements()) { // token has a single certificate
String alias = (String) enume.nextElement();
System.err.println(alias);
Certificate cert = keystorePkcs11.getCertificate(alias);
System.err.println("Cert to string "+cert.toString());
**keystorePkcs11.getKey(alias, pass);** // Error is HERE
PrivateKey priv = (PrivateKey)(keystorePkcs11.getKey(alias, pass));
}
}
} catch (IOException | PKCS11Exception | KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException ex) {
Logger.getLogger(PKCS11Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
完整的输出和错误是:
Token found at position 0 label MTOKEN CRYPTOID model E manufacturerID LONGMAI utcTime serial AE09D489************
A certificate object
Cert to string [
[
Version: V3
Subject: CN=**************, SURNAME=************, GIVENNAME=************, SERIALNUMBER=*************, EMAILADDRESS=**************, OU=OG, O=*****************, L=****, ST=******, C=RO, T=*****
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
...............................
]
Exception in thread "main" java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_ATTRIBUTE_TYPE_INVALID
at sun.security.pkcs11.P11KeyStore.engineGetKey(P11KeyStore.java:330)
at java.security.KeyStore.getKey(KeyStore.java:1023)
at pkcs11test.PKCS11Test.main(PKCS11Test.java:55)
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_ATTRIBUTE_TYPE_INVALID
at sun.security.pkcs11.wrapper.PKCS11.C_GetAttributeValue(Native Method)
at sun.security.pkcs11.wrapper.PKCS11$SynchronizedPKCS11.C_GetAttributeValue(PKCS11.java:1623)
at sun.security.pkcs11.P11KeyStore.loadPkey(P11KeyStore.java:1298)
at sun.security.pkcs11.P11KeyStore.engineGetKey(P11KeyStore.java:315)
... 2 more
谢谢。