ECDiffieHellmanPublicKey из ByteArray (с использованием ECDiffieHellman NamedCurves)
Я работаю над связью nodejs -> C# сервер. Мне нужно защитить соединение между ними, поэтому я выбрал 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 ответ
Вы утверждаете, что содержимое 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 не поддерживают этот метод (из-за его низкой специфичности поведения).