ECDiffieHellmanPublicKey из ByteArray (с использованием ECDiffieHellman NamedCurves) - PullRequest
0 голосов
/ 03 декабря 2018

Я работаю над связью nodejs -> c # server.Мне нужно защитить соединение между ними, поэтому я выбрал ECDiffieHellman в качестве механизма обмена ключами (nodejs поддерживает его).У меня были некоторые проблемы с этим ... Просто мое отсутствие знаний, поэтому я сделал урок, и теперь я могу генерировать и экспортировать ключи, так как base64 и nodejs не имеют проблем с принятием ключа C #, но с другой стороны, C # ... победилдаже не бери его собственный ключ ... error System.Security.Cryptography.CryptographicException: 'The parameter is incorrect.' Да, я знаю, что я делаю что-то неправильно, но что?

using (ECDiffieHellman alice = ECDiffieHellman.Create(ECCurve.NamedCurves.brainpoolP256r1))
{

    var alicePublicKey = Convert.ToBase64String(alice.PublicKey.ToByteArray());
    //NODEJS brainpoolP256r1 publickey 
    var key1 = Convert.FromBase64String("BB92GQLod55fXEhgNxwQcPQFFvph7eIjnSzdNz2PhzUAOcaPEiLBPQR6AL5pqVLFram8OtPapoBGYZn2vaGl+/U=").ToList();
    //test
    var key2 = Convert.FromBase64String(alicePublicKey);
    var keyType = new byte[] { 0x45, 0x43, 0x4B, 0x50 };
    var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 };
    key1.RemoveAt(0);
    key1 = keyType.Concat(keyLength).Concat(key1).ToList();
    byte[] bobKeyBytes = key1.ToArray();
    ECDiffieHellmanPublicKey k = ECDiffieHellmanCngPublicKey.FromByteArray(bobKeyBytes, new CngKeyBlobFormat("ECCPUBLICBLOB")); //error  System.Security.Cryptography.CryptographicException: 'The parameter is incorrect.'
    ECDiffieHellmanPublicKey kk = ECDiffieHellmanCngPublicKey.FromByteArray(key2, new CngKeyBlobFormat("ECCPUBLICBLOB")); // error System.Security.Cryptography.CryptographicException: 'The parameter is incorrect.'
    byte[] aliceKey = alice.DeriveKeyMaterial(k);
    byte[] encryptedMessage = null;
    byte[] iv = null;
    // Send(aliceKey, "Secret message", out encryptedMessage, out iv);
}

Вы можете найти остальную часть истории там ECDH nodejs и ключ C #обмен

1 Ответ

0 голосов
/ 03 декабря 2018

Вы утверждаете, что содержимое base64, входящее в key1, предназначено для brainpoolP256r1.

При декодировании значения мы видим, что это полезная нагрузка в 65 байтов, начинающаяся с 04, которая выглядит как несжатая точкакодирование для кривой с 256-битным простым числом.Пока все хорошо.

Вы даже правильно использовали BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC, но вы не можете импортировать «универсальный именованный ключевой блоб», не указав свойство импорта, которое сообщает ему, какая кривая.

Самый простой способ загрузить ключ из этой точки - это

byte[] keyX = new byte[key1.Length / 2];
byte[] keyY = new byte[keyX.Length];
Buffer.BlockCopy(key1, 1, keyX, 0, keyX.Length);
Buffer.BlockCopy(key1, 1 + keyX.Length, keyY, 0, keyY.Length);

ECParameters parameters = new ECParameters
{
    Curve = ECCurve.NamedCurves.brainpoolP256r1,
    Q =
    {
        X = keyX,
        Y = keyY,
    },
};

byte[] derivedKey;

using (ECDiffieHellman bob = ECDiffieHellman.Create(parameters))
using (ECDiffieHellmanPublicKey bobPublic = bob.PublicKey)
{
    derivedKey = alice.DeriveKeyFromHash(bobPublic, HashAlgorithmName.SHA256);
}

. Я пошел дальше и расширил метод DeriveKeyMaterial до значения, которое он по умолчанию означает с помощью ECDiffieHellmanCng, поскольку другие типы ECDH этого не делают.поддерживать этот метод (из-за его низкой специфичности поведения).

...