简体   繁体   English

ByteArray中的ECDiffieHellmanPublicKey(使用ECDiffieHellman NamedCurves)

[英]ECDiffieHellmanPublicKey from ByteArray (using ECDiffieHellman NamedCurves)

I'm working on communication nodejs -> c# server. 我正在使用通讯nodejs-> c#服务器。 I need to secure connection between them so I chode ECDiffieHellman as the key exchange mechanism (nodejs supports it). 我需要确保它们之间的连接安全,因此我选择使用ECDiffieHellman作为密钥交换机制(nodejs支持它)。 I had some problem with it... Just my lack of knowledge so I've made my lesson and now I can generate and export keys as base64 and nodejs have no problem with accepting c# key but on the other side c# ... won't even take his own key ... error System.Security.Cryptography.CryptographicException: 'The parameter is incorrect.' 我有一些问题...只是我的知识不足,所以我上了一节课,现在我可以生成和导出密钥,因为base64和nodejs在接受c#密钥方面没有问题,但另一方面c#...赢了“甚至拿不到自己的钥匙…… error System.Security.Cryptography.CryptographicException: 'The parameter is incorrect.' Ye I know I'm 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);
}

you can find rest of the story there ECDH nodejs and C# key exchange 您可以在ECDH nodejs和C#密钥交换中找到其余的故事

You're asserting that the base64 contents that go into key1 are for brainpoolP256r1. 您声称进入key1的base64内容用于brainpoolP256r1。

Decoding the value we see that it's a 65 byte payload starting with 04 , which looks like an uncompressed point encoding for a curve with a 256-bit prime. 对该值进行解码,我们看到它是一个以04开头的65字节有效负载,对于带有256位素数的曲线,它看起来像是未压缩的点编码。 So far so good. 到现在为止还挺好。

You've even correctly used BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC, but you can't import a "generic named key blob" without specifying the import property that tells it which curve. 您甚至已经正确使用了BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC,但是如果不指定可告诉它哪个曲线的导入属性,就无法导入“通用命名关键点”。

The easy way that you load the key from this point is 从这一点开始加载密钥的简单方法是

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

I've gone ahead and expanded the DeriveKeyMaterial method into what it means by default with an ECDiffieHellmanCng, since other types of ECDH don't support that method (due to its low specificity of behavior). 我已经将DeriveKeyMaterial方法扩展为DeriveKeyMaterial的默认含义,因为其他类型的ECDH不支持该方法(由于其行为特异性低)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM