我正在使用SoftHSM,并且能够在令牌中生成和存储密钥。为了使用SunPKCS接口,许多方法都需要会话句柄,我对如何检索它们感到茫然。 目前我正在使用SoftHSM和PKCS11如下。注释中的代码是我尝试使用SUNPKCS11接口签名的代码。 任何关于如何包装和解包密钥的示例代码也将非常感激。我正在尝试使用PKCS11从一个令牌备份密钥到另一个令牌,如果我的理解是正确的,那么方法必须是通过包装.... Sitaraman
public static void main(String[] args) {
// TODO code application logic hereString configName = "softhsm.cfg";
try {
// Set up the Sun PKCS 11 provider
String configName = "/etc/softhsm.cfg";
Provider p = new SunPKCS11(configName);
String configName1 = "/etc/softhsm1.cfg";
Provider p1 = new SunPKCS11(configName1);
if (-1 == Security.addProvider(p)) {
throw new RuntimeException("could not add security provider");
}
PKCS11 p11 = PKCS11.getInstance("/usr/local/lib/softhsm/libsofthsm.so", "C_GetFunctionList", null, false);
/* p11.C_GetSessionInfo(0);
CK_INFO cki = p11.C_GetInfo();
long[] slots = p11.C_GetSlotList(true);
String label = new String(p11.C_GetTokenInfo(slots[0]).label);
Object obj = new Object();
long sessionhandle = p11.C_OpenSession(slots[0], 1, null, null);
CK_MECHANISM ckm = new CK_MECHANISM();
ckm.mechanism = PKCS11Constants.CKM_RSA_PKCS;
CK_ATTRIBUTE[] cka = new CK_ATTRIBUTE[1];
CK_ATTRIBUTE[] cka1 = new CK_ATTRIBUTE[1];
long[] keypair =p11.C_GenerateKeyPair(slots[1], ckm, cka, cka1);
*/
//System.out.println("No. of slots" + slots.length + "label" + label);
// Load the key store
char[] pin = "vit12345".toCharArray();
char[] pin1 = "User12345".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS11", p);
KeyStore ks1 = KeyStore.getInstance("PKCS11", p1);
ks.load(null, pin);
ks1.load(null, pin1);
Entry e;
KeyStore.PrivateKeyEntry e1;
// Generate the key
SecureRandom sr = new SecureRandom();
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", p);
keyGen.initialize(1024, sr);
KeyPair keyPair = keyGen.generateKeyPair();
PrivateKey pk = keyPair.getPrivate();
// Java API requires a certificate chain
X509Certificate[] chain = generateV3Certificate(keyPair);
ks.setKeyEntry("ALIAS-GOES-HERE", pk, "1234".toCharArray(), chain);
//ks1.setKeyEntry("ALIAS-GOES-HERE1", pk, "1234".toCharArray(), chain);
ks.store(null);
//ks1.store(null);
Key k = ks.getKey("ALIAS-GOES-HERE", "1234".toCharArray());
System.out.println("key string is " + k.toString());
PrivateKey pk1 = (PrivateKey) k;
System.out.println("OK");
} catch (Exception ex) {
ex.printStackTrace();
}
}
答案 0 :(得分:2)
您可以像使用示例代码中的注释块一样使用SunPKCS11包装器中的方法。
您可以通过以下示例代码获取会话句柄:
CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
PKCS11 p11 = PKCS11.getInstance("D:\\cryptoki.dll", "C_GetFunctionList", initArgs, false);
long hSession = p11.C_OpenSession(0, CKF_SERIAL_SESSION| CKF_RW_SESSION, null, null);
char [] pin = {'1', '2', '3', '4', '5', '6', '7', '8'};
p11.C_Login(hSession, CKU_USER, pin);
// do work
p11.C_Logout(hSession);
p11.C_CloseSession(hSession);
例如,要生成AES密钥并获取生成密钥的句柄,请使用以下(作为示例):
CK_ATTRIBUTE[] aesKeyObject = new CK_ATTRIBUTE[13];
try
{
aesKeyObject[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
aesKeyObject[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_AES);
aesKeyObject[2] = new CK_ATTRIBUTE(CKA_VALUE_LEN, 32);
aesKeyObject[3] = new CK_ATTRIBUTE(CKA_TOKEN, true);
aesKeyObject[4] = new CK_ATTRIBUTE(CKA_LABEL, label);
aesKeyObject[5] = new CK_ATTRIBUTE(CKA_PRIVATE, true);
aesKeyObject[6] = new CK_ATTRIBUTE(CKA_EXTRACTABLE, false);
aesKeyObject[7] = new CK_ATTRIBUTE(CKA_WRAP, true);
aesKeyObject[8] = new CK_ATTRIBUTE(CKA_UNWRAP, true);
aesKeyObject[9] = new CK_ATTRIBUTE(CKA_ENCRYPT, true);
aesKeyObject[10] = new CK_ATTRIBUTE(CKA_DECRYPT, true);
aesKeyObject[11] = new CK_ATTRIBUTE(CKA_TRUSTED, true);
aesKeyObject[12] = new CK_ATTRIBUTE(CKA_ID, 1550);
CK_MECHANISM mech = new CK_MECHANISM(CKM_AES_KEY_GEN);
long newAESKeyHandle = p11.C_GenerateKey(hSession, mech, aesKeyObject);
}catch(Exception e)
{
}
然后您可以使用此句柄来使用新生成的密钥。 此外,PKCS11包装器具有包装和解包密钥的方法,您可以使用这些方法进行备份:
public native byte[] C_WrapKey(long hSession,
CK_MECHANISM pMechanism,
long hWrappingKey,
long hKey) throws PKCS11Exception
public native long C_UnwrapKey(long hSession,
CK_MECHANISM pMechanism,
long hUnwrappingKey,
byte[] pWrappedKey,
CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception