ECDH Nodejs 和 C# 密钥交换

2023-12-03

我迷失了自我,我需要帮助才能走上正确的方向:) 我有一个 Nodejs 服务器,它必须与用 C# 编写的服务器交换一些关键数据,所以在这种情况下,我希望我的数据以某种方式加密。我正在考虑 AES,为了安全地交换密钥,我想使用 ECDH,但我不知道如何使其正常工作...如果我思考正确的方式,我可以使我的 C#“alice”端像这样:

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“Bob”这边是这样的:

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*/);

#大编辑我得到了帮助来自 ByteArray 的 ECDiffieHellmanPublicKey(使用 ECDiffieHellman NamedCurves)现在我有另一个问题-_- 我的 Node js 代码与上面没有改变,但 C# 看起来像:

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) i got iIoH9aJoWf3666QQ6X+kj4iUKrk9j+hbRuXbhgs7YzM=并出alice.DeriveKeyFromHash(bobPublic, HashAlgorithmName.SHA256); I got wJ7O4Hm2Jxs1FcLx6KaMmENvqdTQJPZ/YNSs1+MQDOQ=如果我的想法正确的话,它们应该是平等的。我想错了吗?

#编辑完成!

所以在 js 文件末尾添加这段代码给了我我所需要的。

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

##解决方案##

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 and @马滕·博德维斯

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ECDH Nodejs 和 C# 密钥交换 的相关文章

随机推荐

  • 错误:ORA-00955:名称已被 Oracle 函数中的现有对象使用

    我有一个函数 我正在尝试编译并收到错误Error ORA 00955 name is already used by an existing object 我真的不知道这个错误并尝试搜索这个问题但没有找到任何解决方案 我不知道这是否与任何授
  • Java - 查找最相关数字的算法[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我遇到了问题 但似乎找不到
  • 如何获取我的海龟图形海龟的 X 坐标

    我可以使用以下代码创建一个位于窗口中的乌龟 Turtle t1 new Turtle w 100 100 如果我想知道它的坐标 我可以写 int getX w 但是当我有 2 只海龟 t1 和 t2 时 如果我想知道海龟 1 的 X 坐标
  • 限制从 HTTP 响应读取的字节数

    我需要读取用户提供的 URL 的响应 我不希望他们通过大文件的链接使我的服务器超载 我想最多读取 N 个字节 如果还有更多字节要读取 则返回错误 我可以读取 N 个字节 但是我如何检测该文件不完整 假设远程文件正好是 N 个字节长的极端情况
  • 从 git 中删除已删除的文件:参数列表太长

    我尝试从 git 中删除已删除的文件 git rm git status grep deleted awk print 3 但出现错误mac bash bash usr local git bin git Argument list too
  • 电子邮件的文本区域换行符

    如何从文本区域 html 中获取文本并插入换行符 现在 如果我输入要作为电子邮件发送的信息 它会将所有文本放在同一行上 没有任何换行符 使用 POST field 从表单获取数据并使用 PHP 邮件发送 Use nl2br 功能 它将字符串
  • facebook->getUser() 返回 0

    我认为这是因为用户必须授予对我的 facebook 应用程序的某种访问权限 以便我可以使用 getUser 这是我的代码 所以我想我的问题是 除了提示用户向我的应用程序授予权限之外 是否有任何其他类型的唯一标识符可以从 Facebook 用
  • 如何将 ASP.NET Identity 与您自己的自定义表一起使用

    我有一个非常简单的表 其中用户ID为int 密码为文本 角色为文本 逗号分隔 我可以自定义 ASP NET Identity 结构以将其与我的表一起使用吗 是的 您可以使 Identity 与您的结构配合使用 你必须实施IPasswordV
  • Swift:无法将 NSObject 插入数组,因为它需要 [String]

    我有一个名为 Hashtag 的模型对象 它仅包含一个名为 hashtagName 的可选字符串变量 我从 Firebase 数据库中获取数据 并将主题标签附加到我的 FashionHashtags 中 这是一个 Hashtag 我遇到的问
  • 使用 .NET 连接到 Informix

    服务器信息Sun Microsystems Inc SunOS 5 8 通用补丁 2001 年 10 月服务器 Informix 动态服务器版本 7 31 UD3 信息 Link 从 Net 连接到 Informix 数据库 文章 http
  • getRowHeight() 不适用于 rowModelType = 'infinite' 和最新的 ag-grid 版本

    我在 ag grid 网站上看到此注释 仅在内存行模型中支持更改行高 使用虚拟分页 视口或企业行模型时不能使用可变行高 这是因为这些行模型需要计算出未加载的行的位置 因此需要假设行高是固定的 但是 getRowHeight 在以前的版本 7
  • Websockets、SockJs、Stomp、Spring、RabbitMQ,自动删除用户特定队列

    我希望有人能帮助我解决这个问题 我将 Spring 的 Websocket 支持与 SockJs 和 StompJs 一起使用 我订阅了这样的队列 var socket new SockJS localhost websocket stom
  • 是否可以使用 g++ 或 clang++ 获取矢量化报告 - openmp

    我想要获得重新分级自动矢量化和 openmp SIMD 的矢量化报告 gcc fopenmp simd O3 ffast math march native fopt info omp vec optimized missed clang
  • 如何将图标放置在图像或视频上?

    如何将图标放置在图像或视频上 我希望它位于图像的左下角 当用户单击下载图标时 会出现一条提示 询问他们是否要下载图像 Like so 相关代码 a href https loremflickr com 32 a
  • 使用内部 xml 节点和文本为节点创建 DTD

    我有非常简单的 XML 如下所示
  • 如何将命令行变量的值返回到立即窗口

    情况 我想从 Windows 命令提示符返回字符串变量的实际值 命令 cd C Users User Desktop Testfolder for f eol delims F in dir b od csv do set newest F
  • 在 Python 中读取单个字符(getch 样式)在 Unix 中不起作用

    每当我使用食谱时http code activestate com recipes 134892 我似乎无法让它发挥作用 它总是抛出以下错误 Traceback most recent call last old settings term
  • Jquery:查找文本并替换

    div p apple p p ball p p cat p p dogsss p div 我该如何改变dogsss to dollsss using jquery 您可以使用 each 循环遍历 p 元素 以及 text 更新文本 例如
  • Android M - 自定义权限对话框样式

    在实现新的 Android M 权限模型时 我注意到权限对话框不尊重 styles xml 的主题 在我的 styles xml 中 我重写对话框和警报对话框样式 如下所示
  • ECDH Nodejs 和 C# 密钥交换

    我迷失了自我 我需要帮助才能走上正确的方向 我有一个 Nodejs 服务器 它必须与用 C 编写的服务器交换一些关键数据 所以在这种情况下 我希望我的数据以某种方式加密 我正在考虑 AES 为了安全地交换密钥 我想使用 ECDH 但我不知道