Если все, что вам нужно, это повторно зашифровать один и тот же секрет под другим ключом, вы можете использовать C_Unwrap
для создания временного объекта HSM со значением переведенного секрета, а затем использовать C_Wrap
для шифрования значения этого временного объекта HSM для всех получателей. .
Таким образом, секрет никогда не покинет HSM.
Что-то вроде этого (подтверждено, что работает над SafeNet Luna 7 с RSA-OAEP):
// Your private key for 'decrypting' secret. Must have key unwrapping allowed
CK_OBJECT_HANDLE hsmPrivateKey = ... ;
// Encrypted secret
byte[] wrappedKey = ... ; //
// Template for temporal generic secret key with value of the secret
CK_ATTRIBUTE[] tempTemplate = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA.CLASS, CKO.SECRET_KEY),
new CK_ATTRIBUTE(CKA.KEY_TYPE, CKK.GENERIC_SECRET),
new CK_ATTRIBUTE(CKA.TOKEN, false),
new CK_ATTRIBUTE(CKA.PRIVATE, true),
new CK_ATTRIBUTE(CKA.EXTRACTABLE, true),
new CK_ATTRIBUTE(CKA.SENSITIVE, true),
new CK_ATTRIBUTE(CKA.ENCRYPT, false),
new CK_ATTRIBUTE(CKA.DECRYPT, false),
new CK_ATTRIBUTE(CKA.WRAP, false),
new CK_ATTRIBUTE(CKA.UNWRAP, false),
new CK_ATTRIBUTE(CKA.SIGN, false),
new CK_ATTRIBUTE(CKA.VERIFY, false),
new CK_ATTRIBUTE(CKA.DERIVE, false)
};
// Unwrapping/decryption mechanism
CK_MECHANISM mechanism = ... ;
// Handle for temporal generic secret key with value of the secret
CK_OBJECT_HANDLE temporalValueHandle = new CK_OBJECT_HANDLE();
// Unwrap/decrypt the secret into temporal key
CryptokiEx.C_UnwrapKey(session, mechanism, hsmPrivateKey, wrappedKey, wrappedKey.length, tempTemplate, tempTemplate.length, temporalValueHandle);
// Wrap/encrypt the secret for recipients. Recipient public keys must have key wrapping allowed
for(CK_OBJECT_HANDLE recipientPublicKey : ... ) {
LongRef resSize = new LongRef(0);
CryptokiEx.C_WrapKey(session, mechanism, recipientPublicKey, temporalValueHandle, null, resSize);
byte[] rewrappedKey = new byte[CryptokiUtils.safeIntCast(resSize.value)];
CryptokiEx.C_WrapKey(session, mechanism, recipientPublicKey, temporalValueHandle, rewrappedKey, resSize);
System.out.println("Re-wrapped key: " + bytesToHexString(rewrappedKey));
}
// Delete temporal generic secret key
CryptokiEx.C_DestroyObject(session, temporalValueHandle);
Удачи!
person
vlp
schedule
02.08.2019