Я хочу создать цифровую подпись с использованием стандарта pkcs11. Предположим, что у меня уже есть пара открытого и закрытого ключей, которая хранится на моей смарт-карте. Это клавиши были сгенерирован с помощью следующего кода:Как повторно использовать существующий закрытый ключ для генерации цифровой подписи с использованием смарт-карты и PKCS # 11
byte[] ckaId = session.GenerateRandom(20);
// Prepare attribute template of new public key
var publicKeyAttributes = new List<ObjectAttribute>();
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, PKCS11Settings.ApplicationName));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY_RECOVER, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_WRAP, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_MODULUS_BITS, 1024));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));
// Prepare attribute template of new private key
var privateKeyAttributes = new List<ObjectAttribute>();
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, PKCS11Settings.ApplicationName));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SENSITIVE, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN_RECOVER, true));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_UNWRAP, true));
// Specify key generation mechanism
Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN);
// Generate key pair
session.GenerateKeyPair(mechanism, publicKeyAttributes, privateKeyAttributes, out publicKeyHandle, out privateKeyHandle);
Теперь я могу использовать эти ключи, чтобы подписать какие-то данные. Например:
var mechanism = new Mechanism(CKM.CKM_RSA_PKCS);
byte[] byteContent = (ConvertUtils.Utf8StringToBytes("Hello World!!!"));
byte[] signature = session.Sign(mechanism, derivedKey, byteContent);
Этот код работает прекрасно, когда вы хотите создать ключи, а затем использовать его в методе C_sign
Но как получить доступ к уже существующим ключам, чтобы сделать подобную операцию? Как я понимаю, я должен получить закрытый ключ из существующего с помощью метода C_Derrive() и использовать его в методе C_Sign(). Для этого я написал следующий код:
// Prepare attribute template of new key
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_DERIVE, true));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_EXTRACTABLE, true));
// Specify key generation mechanism
Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS);
// Generate key
ObjectHandle baseKey = session.GenerateKey(mechanism, objectAttributes);
byte[] dt = session.GenerateRandom(24);
// Specify mechanism parameters
var mechanismParams = new CkKeyDerivationStringData(dt);
// Specify derivation mechanism with parameters
Mechanism mech = new Mechanism(CKM.CKM_RSA_PKCS, mechanismParams);
// Derive key
ObjectHandle derivedKey = session.DeriveKey(mech, baseKey, null);
byte[] byteContent = (ConvertUtils.Utf8StringToBytes("Hello World!"));
byte[] signature = session.Sign(mech, derivedKey, byteContent);
Но когда я запускаю этот код он будет бросать следующую ошибку:
Method C_GenerateKey returned CKR_MECHANISM_INVALID
Может кто-нибудь сказать мне, что я делаю неправильно и как решить Эта проблема ?
Большое спасибо! Это помогает мне, но после добавления дополнительных ключевых атрибутов (набранных в вашем ответе) в коде генерации ключей. – Tequila