Есть вопросы о секретном соглашении от реализации ECDiffieHellmanCng в .net framework 4.7?

У меня есть следующий код:

        var curve = ECCurve.NamedCurves.nistP256;
        var ecdhSender = ECDiffieHellman.Create(curve);
        var ecdhReceiver = ECDiffieHellman.Create(curve);

Насколько я понимаю, я должен иметь возможность вычислить секретное соглашение либо с помощью объекта ecdhSender с использованием ecdhReceiver.PublicKey, либо с использованием объекта ecdhReceiver с ecdhSender.PublicKey, и оба значения секретного соглашения должны быть одинаковыми. Если это неверное предположение, пожалуйста, дайте мне знать.

Поскольку ECDiffieHellman.Create возвращает тип ECDiffieHellman, я написал следующий код, чтобы получить секретное соглашение:

        string receiverHexString = null;
        using (SafeNCryptSecretHandle secretAgreement = (ecdhReceiver as ECDiffieHellmanCng).DeriveSecretAgreementHandle(ecdhSender.PublicKey))
        {
            byte[] secretAgreementBytes = new byte[32];
            IntPtr pointer = secretAgreement.DangerousGetHandle();
            Marshal.Copy(pointer, secretAgreementBytes, 0, secretAgreementBytes.Length);
            receiverHexString = BitConverter.ToString(secretAgreementBytes).Replace("-", string.Empty).ToLower();
            Console.WriteLine($"receiver secretAgreement: 0x{receiverHexString}");
        }

        string senderHexString = null;
        using (SafeNCryptSecretHandle secretAgreement = (ecdhSender as ECDiffieHellmanCng).DeriveSecretAgreementHandle(ecdhReceiver.PublicKey))
        {
            byte[] secretAgreementBytes = new byte[32];
            IntPtr pointer = secretAgreement.DangerousGetHandle();
            Marshal.Copy(pointer, secretAgreementBytes, 0, secretAgreementBytes.Length);
            senderHexString = BitConverter.ToString(secretAgreementBytes).Replace("-", string.Empty).ToLower();
            Console.WriteLine($"sender secretAgreement: 0x{senderHexString}");
        }

        Assert.AreEqual(receiverHexString, senderHexString);

Мое утверждение не работает. Очевидно, я что-то делаю не так (если тайные соглашения должны быть одинаковыми).

Это как я извлекаю байты из ручки? Или что-то другое?


person Raghu    schedule 13.10.2017    source источник
comment
Что вы пытаетесь достичь? Структура NCRYPT_SECRET_HANDLE непрозрачна, вы не должны читать ее память.   -  person bartonjs    schedule 16.10.2017
comment
Попытка проверить результаты от партнера с подробными шагами. Не могли бы вы прокомментировать, верно ли мое предположение в первой части моего вопроса?   -  person Raghu    schedule 16.10.2017


Ответы (1)


По состоянию на последний раз, когда я проверял, нет задокументированного способа получить необработанное значение секретного соглашения из CNG, поэтому . NET не раскрывает его.

Ожидаемое использование ECDH в .NET:

ECCurve curve = ECCurve.NamedCurves.nistP256;

// Usually you'll only have one private key (yours), so this isn't representative of
// real code.  An `ECDiffieHellman` object doesn't necessarily have a private key,
// but an `ECDiffieHellmanPublicKey` object definitely doesn't.
using (ECDiffieHellman bobPrivate = ECDiffieHellman.Create(curve))
using (ECDiffieHellman alicePrivate = ECDiffieHellman.Create(curve))
using (ECDiffieHellmanPublicKey bobPublic = bobPrivate.PublicKey)
using (ECDiffieHellmanPublicKey alicePublic = alicePrivate.PublicKey)
{
    byte[] ba = bobPrivate.DeriveKeyFromHash(alicePublic, HashAlgorithmName.SHA256);
    byte[] ab = alicePrivate.DeriveKeyFromHash(bobPublic, HashAlgorithmName.SHA256);

    // ba and ab have the same contents.
}

Есть также

  • DeriveKeyFromHash(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] secretPrepend, byte[] secretAppend)
  • DeriveKeyFromHmac(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] hmacKey)
  • DeriveKeyFromHmac(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend)
  • DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)

Если bobPrivate и alicePublic (или, наоборот, alicePrivate и bobPublic) неизменны, то предоставление одних и тех же входных данных даст одинаковые выходные данные.

Примечание. По возможности не следует говорить конкретно о ECDiffieHellmanCng. Когда ECDH в конце концов превратится в .NET Standard, класс ECDHCng этого не сделает. Начиная с .NET 4.6.2 в базовом классе можно делать все (кроме открытия постоянных ключей); и .NET Core имеет тенденцию не возвращать общедоступные типы из своих Create() фабричных методов.

person bartonjs    schedule 16.10.2017