来自 ByteArray 的 ECDiffieHellmanPublicKey(使用 ECDiffieHellman NamedCurves)

ECDiffieHellmanPublicKey from ByteArray (using ECDiffieHellman NamedCurves)

我正在研究通信 nodejs -> c# 服务器。 我需要保护它们之间的连接,所以我选择 ECDiffieHellman 作为密钥交换机制(nodejs 支持它)。我遇到了一些问题......只是我缺乏知识所以我已经完成了我的课程现在我可以生成和导出密钥作为 base64 和 nodejs 接受 c# 密钥没有问题但另一方面 c# ... 赢了甚至拿他自己的钥匙... error System.Security.Cryptography.CryptographicException: 'The parameter is incorrect.' Ye I know I making sth wrong but what?

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);
}

你可以在那里找到故事的其余部分

您断言进入 key1 的 base64 内容适用于 brainpoolP256r1。

解码值,我们看到它是一个以 04 开头的 65 字节有效负载,它看起来像是对具有 256 位素数的曲线的未压缩点编码。到目前为止一切顺利。

您甚至正确地使用了 BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC,但是您不能在不指定导入 属性 的情况下导入 "generic named key blob" 来告诉它哪条曲线。

从这一点加载密钥的简单方法是

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 不支持该方法(由于其行为特异性较低)。