Nodejs和C#使用ECDH算法交换秘钥

server/2024/10/18 18:17:50/

转载于:https://bkssl.com/document/nodejs-csharp-ecdh.html

nodejs的ECDH算法在进行computeSecret的时候不会自动进行HASH运算,但C#的ECDH算法必须指定HASH算法。

两边算法必须使用相同的椭圆曲线和Hash算法,例如下面用例都是用的SHA256。
双方交换公钥,计算得到共享秘钥:SharedSecret。

用例使用readline去交换公钥,实际一般运行在其他协议中,像SSH2等。
单纯秘钥交换并不安全,需要增加其他手段保证不被中间人监听、修改,例如ssh2使用serverhostkey对秘钥交换的数据进行签名。

nodejs测试代码

import readline from 'readline';import crypto  from 'crypto';function computeHash(data, alg){const hashAlg = crypto.createHash(alg || 'SHA256');hashAlg.update(data);return hashAlg.digest();
}const reader = readline.createInterface({input: process.stdin,output: process.stdout
});const ecdh = crypto.createECDH('prime256v1');const e = ecdh.generateKeys();console.log("Local Public Key:" + e.toString('base64'));reader.question('Please Input Remote PublicKey:', key => {console.log("Remote Public Key:" + key);let sharedSecret = ecdh.computeSecret(Buffer.from(key, 'base64'));//计算共享秘钥,需要先HASH运算,以兼容C#sharedSecret = computeHash(sharedSecret);console.log("Shared Secret: " + sharedSecret.toString('base64'));
})// 控制台输出
// Local Public Key:BGLb5Sddo8N5sd1/+a7vhwb66QFMqAJtNFvEISecSzrBP3DjEr3R6vHeefI100yVDCnPQLNmgv56ampL+tNBc2c=
// Please Input Remote PublicKey:BASkBjbrTNysfXrcqyCOWuVgWVRF8a3VTufPLl99PFdY4+oj2d2kImu1OoZLMMoRKwul02gP27dWRoMCGicHjuQ=
// Remote Public Key:BASkBjbrTNysfXrcqyCOWuVgWVRF8a3VTufPLl99PFdY4+oj2d2kImu1OoZLMMoRKwul02gP27dWRoMCGicHjuQ=
// Shared Secret: EvhnVuNRa3dBqIFDyfSQfYmRF4/fPgJHDRZG5xB6HnA=

C#测试代码
 

var ecdh = ECDiffieHellmanHelper.New();
byte[] localPublicKey = ECDiffieHellmanHelper.CreateKeyExchange(ecdh);Console.WriteLine("Local Public Key: {0}", localPublicKey.ToBase64String());Console.WriteLine("Please Input Remote Public Key:");
string remotePublicKey = Console.ReadLine();Console.WriteLine("Remote Public Key: {0}", remotePublicKey);byte[] sharedSecret = ECDiffieHellmanHelper.DecryptKeyExchange(ecdh, remotePublicKey.AsBase64String());Console.WriteLine("Shared Secret: {0}", sharedSecret.ToBase64String());// 控制台输出
// Local Public Key: BASkBjbrTNysfXrcqyCOWuVgWVRF8a3VTufPLl99PFdY4+oj2d2kImu1OoZLMMoRKwul02gP27dWRoMCGicHjuQ=
// Please Input Remote Public Key:
// BGLb5Sddo8N5sd1/+a7vhwb66QFMqAJtNFvEISecSzrBP3DjEr3R6vHeefI100yVDCnPQLNmgv56ampL+tNBc2c=
// Remote Public Key: BGLb5Sddo8N5sd1/+a7vhwb66QFMqAJtNFvEISecSzrBP3DjEr3R6vHeefI100yVDCnPQLNmgv56ampL+tNBc2c=
// Shared Secret: EvhnVuNRa3dBqIFDyfSQfYmRF4/fPgJHDRZG5xB6HnA=

C#的ECDiffieHellmanHelper类实现

internal class ECPublicKey : ECDiffieHellmanPublicKey
{private readonly ECParameters parameters;public ECPublicKey(ECParameters parameters){this.parameters = parameters;}public override ECParameters ExportParameters() => parameters;public override ECParameters ExportExplicitParameters() => parameters;}public class ECDiffieHellmanHelper
{//可以选择其他的曲线private static readonly ECCurve curve = ECCurve.NamedCurves.nistP256;public static ECDiffieHellman New(ECCurve curve) => ECDiffieHellman.Create(curve);public static ECDiffieHellman New() => ECDiffieHellman.Create(curve);public static byte[] CreateKeyExchange(ECDiffieHellman ecdh){var args = ecdh.PublicKey.ExportParameters();int blockSize = args.Q.X.Length;byte[] buffer = new byte[blockSize * 2 + 1];buffer[0] = 0x4;args.Q.X.CopyTo(buffer, 1);args.Q.Y.CopyTo(buffer, blockSize + 1);return buffer;}public static byte[] DecryptKeyExchange(ECDiffieHellman ecdh, byte[] serverPublicKey){ReadOnlySpan<byte> bytes = new(serverPublicKey);int length = (serverPublicKey.Length - 1) / 2;ECPublicKey thirdPublicKey = new (new ECParameters{Curve = curve,D = null,Q = new ECPoint{X = bytes.Slice(1, length).ToArray(),Y = bytes.Slice(1 + length, length).ToArray(),}});return ecdh.DeriveKeyFromHash(thirdPublicKey, HashAlgorithmName.SHA256);}
}

 


http://www.ppmy.cn/server/131691.html

相关文章

3.stable-diffusion1.10.0精准控制图-ControlNet插件的安装

安装 Controlnet 插件 注&#xff1a;从网址安装可以保证插件的更新能在 WebUI 中自动显示&#xff0c;如果是下载压缩包文件放进根目录&#xff0c;就无法自动更新。下面执行网址安装。 打开 WebUI&#xff0c;点击“扩展”选项卡&#xff0c;选择“从网址安装”&#xff0c;…

详细分析Redisson分布式锁中的renewExpiration()方法

目录 一、Redisson分布式锁的续期 整体分析 具体步骤和逻辑分析 为什么需要递归调用&#xff1f; 定时任务的生命周期&#xff1f; 一、Redisson分布式锁的续期 Redisson是一个基于Redis的Java分布式锁实现。它允许多个进程或线程之间安全地共享资源。为了实现这一点&…

网站服务器监控:Apache指标解读

监控易是一款专业的IT监控软件&#xff0c;能够实时监控各类IT资源和应用的状态&#xff0c;确保系统的稳定运行。在网站服务器监控中&#xff0c;Apache作为广泛使用的Web服务器软件&#xff0c;其性能和稳定性对于网站的正常运行至关重要。下面&#xff0c;我们将对监控易中A…

【自动化】Java Access Bridge 使用说明

【自动化】Java Access Bridge 使用说明 Java Access Bridge是一项在Microsoft Windows动态链接库(DLL)中公开Java Accessibility API的技术,使实现Java Accessibility API的 Java应用程序对Microsoft Windows系统上的辅助技术可见。 开启jab服务 1 、首先获取java版本信…

Python速成笔记——知识:GUI自动化控制鼠标

图形用户界面自动化(GUI自动化):通过程序控制其他应用,向它们发送虚拟的按键和鼠标点击事件,模拟用户在计算机前进行操作。 功能:自动化解决需要大量机械式点击鼠标或填写表格的任务。 模块:pyautogui安装:pip install --user pyautoguiGUI自动化程序中断 将鼠标指针滑…

python数据分析与可视化介绍

本文主要讲述了数据可视化的基础知识&#xff0c;包括什么是数据可视化&#xff0c;数据可视化应用以及Python可视化工具库。 什么是数据可视化 可视化是一种通过视觉的方式有效传达信息的技术。数据可视化旨在借助于图形化手段&#xff0c;将数据以视觉形式来呈现&#xff0c…

VScode连接服务器配置c、c++编程环境

在 VS Code 中配置远程服务器的 C/C 编程环境&#xff0c;可以使用 VS Code 的 Remote-SSH 扩展来通过 SSH 连接到远程服务器&#xff0c;并在服务器上编写、编译和调试 C/C 代码。 以下是详细的配置步骤&#xff1a; 1. 在本地机器上安装 VS Code 和扩展 安装 VS Code&#…

蓝桥杯备赛(c/c++)

排序 9. 实现选择排序 10. 实现插入排序 11. 实现快速排序 12. 实现归并排序 13. 实现基数排序 14. 合并排序数组