public static byte[] DeriveSecret(EcIdentifier ecIdentifier, EcKeyPair publicKeyPair, string password) { using (Pkcs11 pk = new Pkcs11(LibraryPath, false)) { var slot = pk.GetSlotList(false) .First(s => { try { bool found; using (Session session = s.OpenSession(true)) { found = s.GetTokenInfo().SerialNumber == ecIdentifier.TokenSerialNumber; } return(found); } catch { return(false); } }); using (Session session = slot.OpenSession(false)) { session.Login(CKU.CKU_USER, password); var objectPrivate = GetObjectHandle(ecIdentifier.KeyLabel, session, CKO.CKO_PRIVATE_KEY); var publicKey = publicKeyPair.ToDre(); byte[] data = session.GenerateRandom(32); var mechanism = new Mechanism(CKM.CKM_ECDH1_DERIVE, new CkEcdh1DeriveParams(0, null, publicKey)); var deriveAttributes = new List <ObjectAttribute> { new ObjectAttribute(CKA.CKA_TOKEN, false), new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY), new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_GENERIC_SECRET), new ObjectAttribute(CKA.CKA_SENSITIVE, false), new ObjectAttribute(CKA.CKA_EXTRACTABLE, true), new ObjectAttribute(CKA.CKA_ENCRYPT, true), new ObjectAttribute(CKA.CKA_DECRYPT, true), new ObjectAttribute(CKA.CKA_WRAP, true), new ObjectAttribute(CKA.CKA_UNWRAP, true), new ObjectAttribute(CKA.CKA_VALUE_LEN, 320 / 8), }; var derivedKey = session.DeriveKey(mechanism, objectPrivate, deriveAttributes); var derivedSecret = GetDataFromObject(derivedKey, session, CKA.CKA_VALUE); return(SHA512.Create().ComputeHash(derivedSecret)); } } }
private static byte[] GetSecretKey(EcIdentifier ecIdentifier, EllipticCurveEncryptionInformation hybridFileInfo, string password) { var publicKey = Encryption.NitroKey.EllipticCurveCryptographer.GetPublicKey(ecIdentifier, password); var derivedSecret = hybridFileInfo.DerivedSecrets.FirstOrDefault(secret => publicKey.CheckPublicKeyHash(secret.PublicKeyHash, secret.PublicKeyHashSalt)); var ds = Encryption.NitroKey.EllipticCurveCryptographer.DeriveSecret(ecIdentifier, hybridFileInfo.EphemeralKey, password); var derivedSecretInputStream = new MemoryStream(derivedSecret.EncryptedSharedSecret); var derivedSecretOutputStream = new MemoryStream(); SymmetricEncryption.Decrypt(derivedSecretInputStream, derivedSecretOutputStream, ds); var secretKey = derivedSecretOutputStream.ToArray(); return(secretKey); }
public static EcKeyPair GetPublicKey(EcIdentifier ecIdentifier, string password) { byte[] ecPoint = null; using (Pkcs11 pk = new Pkcs11(LibraryPath, false)) { var slot = pk.GetSlotList(false) .First(s => { try { bool found; using (Session session = s.OpenSession(true)) { found = s.GetTokenInfo().SerialNumber == ecIdentifier.TokenSerialNumber; } return(found); } catch { return(false); } }); using (Session session = slot.OpenSession(false)) { session.Login(CKU.CKU_USER, password); // CKO_PUBLIC_KEY, see https://www.cryptsoft.com/pkcs11doc/v220/group__SEC__12__3__3__ECDSA__PUBLIC__KEY__OBJECTS.html var objectPublic = GetObjectHandle(ecIdentifier.KeyLabel, session, CKO.CKO_PUBLIC_KEY); var @params = GetDataFromObject(objectPublic, session, CKA.CKA_EC_PARAMS); ecPoint = GetDataFromObject(objectPublic, session, CKA.CKA_EC_POINT); var paramsHex = BitConverter.ToString(@params).ToLower().Replace("-", null); if (paramsHex != BrainpoolOid) { throw new Exception(); } } } return(EcKeyPair.CreateFromAnsi(ecPoint)); }