我正在用SmartCard D-信任证书v2.6.1测试电子签名申请.
我开发了一个web服务应用程序,它从SmartCard读取,获取可用的插槽和证书,目的是对文档进行签名。
我使用的是Java,使用的是iText(5.4.3版)和BounceCastle (Version15on-1.48),但是当我试图获取可用的插槽时会出现一个问题:它返回1000、0和1,当我想访问证书时,应用程序遇到了一个问题:
初始化失败的方法调用Security.addProvider(providerPKCS11);
我使用库personal.dll,放在C:\Program (X86)\Personal\中。
Java中的代码是:
public class SmartCard
{
public static long[] getSlots (String libraryPath) throws IOException
{
CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
String functionList = "C_GetFunctionList";
initArgs.flags = 0;
PKCS11 tmpPKCS11 = null;
long[] slotList = null;
try
{
try
{
tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, false);
}
catch (IOException ex)
{
ex.printStackTrace();
throw ex;
}
}
catch (PKCS11Exception e)
{
try
{
initArgs = null;
tmpPKCS11 = PKCS11.getInstance(libraryPath, functionList, initArgs, true);
}
catch (IOException ex)
{
ex.printStackTrace();
}
catch (PKCS11Exception ex)
{
ex.printStackTrace();
}
}
try
{
slotList = tmpPKCS11.C_GetSlotList(true);
System.out.println("**** SLOTS ****");
System.out.println(String.format("Hay %d slots.", slotList.length));
System.out.println("------");
for (long slot : slotList)
{
CK_TOKEN_INFO tokenInfo = tmpPKCS11.C_GetTokenInfo(slot);
System.out.println("slot: " + slot + "\nmanufacturerID: "
+ String.valueOf(tokenInfo.manufacturerID)
+ "\nmodel: " + String.valueOf(tokenInfo.model));
System.out.println("----");
}
}
catch (PKCS11Exception ex)
{
ex.printStackTrace();
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
tmpPKCS11 = null;
}
return slotList;
}
public static String getCertificadosInfo(String numeroPIN, String namePkcs11, String nameLibreria, long slotID) throws Exception
{
String strRetorno = "";
KeyStore ks = null;
Provider providerPKCS11 = null;
try
{
BouncyCastleProvider providerBC = new BouncyCastleProvider();
Security.addProvider(providerBC);
String strPass = numeroPIN;
char[] pass = null;
if (strPass != null)
pass = strPass.toCharArray();
String configFilePath = String.Format("name=%s\nlibrary=%s\nslotListIndex=%d", namePkcs11, nameLibreria, slotID);
ByteArrayInputStream bais = new ByteArrayInputStream(configFilePath.getBytes());
providerPKCS11 = new SunPKCS11(bais);
Security.addProvider(providerPKCS11); // HERE THE EXCEPTION IS THROWN: Initialization failed
ks = KeyStore.getInstance("PKCS11");
ks.load(null, pass);
boolean bNoHayCertificados = true;
Enumeration<String> oEnum = ks.aliases();
.......有人知道问题出在哪里吗?
非常感谢,我会感谢你的帮助。
发布于 2014-07-26 14:13:19
我不认为返回的数字有什么问题。如果直接调用PKCS#11模块,一切都很好。可用插槽数表示可能包含令牌的时隙数。由于您可以有任意数量的读卡器,插槽的数量是不确定的。你不应该在意,除非其中一个里面有个记号。
可能您不应该加载提供程序两次。在getSlots中直接加载它一次,然后让Sun PKCS#11提供程序再次加载它。否则,您应该查看Sun PKCS#11日志记录,以了解为什么.dll不会初始化。您可以通过向VM/运行时调用提供-Djava.security.debug=sunpkcs11,pkcs11 (java或javaw)来启用它。
https://stackoverflow.com/questions/24908297
复制相似问题