ECDH nodejs和C#密钥交换 [英] ECDH nodejs and C# key exchange

查看:133
本文介绍了ECDH nodejs和C#密钥交换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经迷失了自我,我需要帮助才能朝着正确的方向发展:) 我有nodejs服务器,它必须与用C#编写的服务器交换一些关键数据,因此在这种情况下,我希望以某种方式对我的数据进行加密.我在考虑AES,并且为了安全地交换密钥,我想使用ECDH,但是我不知道如何使其正常工作...如果我想的正确,我可以使C#的"allice"面像这样:

I've lost my self and I need help to go in the right direction :) I have nodejs server that have to exchange some critical data with the server that is written in C#, so in that case, I want my data to be encrypted somehow. I was thinking about AES, and to safely exchange keys i want to use ECDH but I don't know how to make it work correctly... If I'm thinking right way I can make my C# "allice" side like this :

ECDiffieHellman alice = ECDiffieHellman.Create(ECCurve.NamedCurves.brainpoolP192t1);
var aliceKey = alice.PublicKey;
var ketyToExport = Convert.ToBase64String(aliceKey.ToByteArray());
//send ketyToExport to nodejs
//KEY FROM nodejs
var key1 = Convert.FromBase64String("BIzSJ1dmTXpSS8rqkVFISZ+vumhqXYMWfWoU5vB9GHhOtxxDInu/GZ92VJpqhrE3vw==").ToList();
var keyType = new byte[] { 0x45, 0x43, 0x4B, 0x31 };
var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 };
key1.RemoveAt(0);
key1 = keyType.Concat(keyLength).Concat(key1).ToList();
byte[] bobKeyBytes = key1.ToArray();
//and I have a problem with that line bellow, I do not know how to make it work
var aliceSecret = alice.DeriveKeyMaterial(/*ECDiffieHellmanPublicKey bobKeyBytes*/);

nodejs的鲍勃"面像这样:

And nodejs "Bob" side like this:

const crypto = require("crypto");
const bob = crypto.createECDH('brainpoolP192t1')
const bobKey = bob.generateKeys('base64');
var bobLength = Buffer.from(bobKey, 'base64').length;
//send bobkey to c#
//recive alicekey
var tmp = "RUNLUBgAAAAR9C7kO2o+vxNT/UBvvEuJHNdI8NfU4fUxUT431ER1q3kJbeUVHepoG5SWUM2NHj8="
var aliceKeyBuffer = Buffer.from(tmp, 'base64');
var aliceKey = Buffer.alloc(bobLength)
aliceKeyBuffer.copy(aliceKey, 1, 8);
aliceKey[0] = 4;
bob.computeSecret(aliceKey);
//create aes 
//get mesage and iv ...

好的,所以我已经对所有这些进行了一些调整,但是现在我不知道该行如何处理才能工作... var aliceSecret = alice.DeriveKeyMaterial(/*ECDiffieHellmanPublicKey bobKeyBytes*/);

Okay so I've made some adjustments to all of that but right now I don't know what to do about this line how to make it work... var aliceSecret = alice.DeriveKeyMaterial(/*ECDiffieHellmanPublicKey bobKeyBytes*/);

#BIG EDIT 我在从ByteArray中使用ECDiffieHellmanPublicKey获得了帮助(使用ECDiffieHellman NamedCurves) 现在我有另一个问题-_- 我的节点js代码没有从上面改变,但是c#看起来像这样:

#BIG EDIT I got help in ECDiffieHellmanPublicKey from ByteArray (using ECDiffieHellman NamedCurves) and now I have another problem -_- my node js code didn't change from above but c# looks like:

using (ECDiffieHellman alice = ECDiffieHellman.Create(ECCurve.NamedCurves.brainpoolP256r1))
{
    var alicePublicKey = Convert.ToBase64String(alice.PublicKey.ToByteArray());
    //NODEJS brainpoolP256r1 publickey 
    var key1 = Convert.FromBase64String("BASsbkule53ARqlMBA8hYysyyoRi3xGxGnSzIJ2fS5FlLniQD/zYiiGUVydmO/BBkQwVTUo5f4OMCxVNtQ/LuMQ=");
    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);
    }
    var aliceKey = Convert.ToBase64String(derivedKey);
    byte[] encryptedMessage = null;
    byte[] iv = null;
    // Send(aliceKey, "Secret message", out encryptedMessage, out iv);
}

它正在工作,但是它为我提供了不同的密钥... 从bob.computeSecret(aliceKey)中我得到了iIoH9aJoWf3666QQ6X+kj4iUKrk9j+hbRuXbhgs7YzM=alice.DeriveKeyFromHash(bobPublic, HashAlgorithmName.SHA256); 我得到了wJ7O4Hm2Jxs1FcLx6KaMmENvqdTQJPZ/YNSs1+MQDOQ= 如果我在正确地思考的话,它们应该相等.我在想错吗?

and it is working but it gives me different secret keys ... out of bob.computeSecret(aliceKey) i got iIoH9aJoWf3666QQ6X+kj4iUKrk9j+hbRuXbhgs7YzM= and out of alice.DeriveKeyFromHash(bobPublic, HashAlgorithmName.SHA256); I got wJ7O4Hm2Jxs1FcLx6KaMmENvqdTQJPZ/YNSs1+MQDOQ= if I'm thinking correctly they should be equal. am I thinking wrong?

#EDIT完成!!

因此,将这段代码添加到js文件的末尾可以满足我的需求.

So this adding this code on end of js file gave me what I needed.

const hash = crypto.createHash('sha256');
var tt = bob.computeSecret(aliceKey);
hash.update(tt);
console.log(hash.digest('base64'));

推荐答案

## SOLUTION ##

C#

class Program
{
    static void Main(string[] args)
    {
        using (ECDiffieHellman alice = ECDiffieHellman.Create(ECCurve.NamedCurves.brainpoolP256r1))
        {
            var alicePublicKey = Convert.ToBase64String(alice.PublicKey.ToByteArray());
            //send alicePublicKey
            var nodejsKey = ""; //NODEJS brainpoolP256r1 publickey  base64
            byte[] nodejsKeyBytes= Convert.FromBase64String(nodejsKey);

            var aliceKey = Convert.ToBase64String(getDeriveKey(nodejsKeyBytes,alice));
            byte[] encryptedMessage = null;
            byte[] iv = null;
            // Send(aliceKey, "Secret message", out encryptedMessage, out iv);
        }
    }
    static byte[] getDeriveKey(byte[] key1, ECDiffieHellman alice)
    {
        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)
        {
            return derivedKey = alice.DeriveKeyFromHash(bobPublic, HashAlgorithmName.SHA256);
        }
    }
}

NODEJS

const crypto = require("crypto");
const bob = crypto.createECDH('brainpoolP256r1')
bob.generateKeys();
const bobKey = bob.getPublicKey('base64');
var bobLength = Buffer.from(bobKey, 'base64').length;
//send bobkey to c#
//recive alicekey

var alicePublicKey = "RUNLUCAAAAB/xP7JhSIhYIYAijyC2zHu7obB5CwfK/ynQPxcRAIhBI6OLRRcHyPo61AhfSZN3qA2vGDfWO2mrdWWvqqhVaDf";
var aliceKeyBuffer = Buffer.from(alicePublicKey, 'base64');
var aliceKey = Buffer.alloc(bobLength)
aliceKeyBuffer.copy(aliceKey, 1, 8);
aliceKey[0] = 4;
const hash = crypto.createHash('sha256');
var tt = bob.computeSecret(aliceKey);
var bobSecretKey = hash.update(tt).digest('base64');

非常感谢 @bartonjs 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆