c# - 来自 ByteArray 的 ECDiffieHellmanPublicKey(使用 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# 密钥交换
解决方案
您断言进入的 base64 内容key1
是用于 BrainpoolP256r1。
解码我们看到它是一个以 开头的 65 字节有效负载的值04
,它看起来像一个未压缩的点编码,用于具有 256 位素数的曲线。到现在为止还挺好。
您甚至正确地使用了 BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC,但是如果不指定告诉它哪条曲线的导入属性,则无法导入“通用命名密钥 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 不支持该方法(由于其行为特异性低)。
推荐阅读
- azure-databricks - 是否可以在数据块增量表的同一列中存储 2 种不同的结构类型?
- azure - 如何从 Azure Databricks UI 实时发送响应?
- three.js - 我的three.js 线条几何图形未显示在屏幕上
- python - AttributeError“类名”对象没有属性“方法”
- flutter - 不确定如何正确实现 ChangeNotifierProvider 以记住 Flutter 中的登录用户
- javascript - 将数据映射到表
- python - 在数据框中计算 - 为什么我在这里得到 KeyError?
- scala - 测试 Akka-http 并出现错误:没有类型的隐式参数:Emptiness[Seq[Rejection]]
- angular - 如何使侧导航的图标响应并与我的侧导航的宽度完全匹配?
- python - 序列项 0:预期的 str 实例,找到 bool (Odoo 14)