当前位置:首页 > JavaScript

js ecdh实现

2026-02-01 15:06:03JavaScript

ECDH 密钥交换实现

ECDH(Elliptic Curve Diffie-Hellman)是一种基于椭圆曲线的密钥交换算法,用于在不安全的通信信道上安全地协商共享密钥。以下是使用 JavaScript 实现 ECDH 密钥交换的步骤。

生成密钥对

使用 Web Crypto API 生成 ECDH 密钥对。需要指定椭圆曲线名称(如 P-256、P-384 或 P-521)。

async function generateKeyPair() {
  const keyPair = await window.crypto.subtle.generateKey(
    {
      name: "ECDH",
      namedCurve: "P-256",
    },
    true,
    ["deriveKey", "deriveBits"]
  );
  return keyPair;
}

导出公钥

将生成的公钥导出为可传输的格式(如 JWK 或 ArrayBuffer)。

async function exportPublicKey(publicKey) {
  const exported = await window.crypto.subtle.exportKey("jwk", publicKey);
  return exported;
}

导入公钥

将接收到的公钥导入为 CryptoKey 对象,以便用于密钥派生。

async function importPublicKey(jwkKey) {
  const publicKey = await window.crypto.subtle.importKey(
    "jwk",
    jwkKey,
    {
      name: "ECDH",
      namedCurve: "P-256",
    },
    true,
    []
  );
  return publicKey;
}

派生共享密钥

使用本地私钥和对方的公钥派生共享密钥。

async function deriveSharedSecret(privateKey, publicKey) {
  const sharedSecret = await window.crypto.subtle.deriveBits(
    {
      name: "ECDH",
      public: publicKey,
    },
    privateKey,
    256
  );
  return sharedSecret;
}

完整示例

以下是一个完整的 ECDH 密钥交换示例:

async function runECDHExchange() {
  // Alice 生成密钥对
  const aliceKeyPair = await generateKeyPair();
  const alicePublicKey = await exportPublicKey(aliceKeyPair.publicKey);

  // Bob 生成密钥对
  const bobKeyPair = await generateKeyPair();
  const bobPublicKey = await exportPublicKey(bobKeyPair.publicKey);

  // Alice 使用 Bob 的公钥派生共享密钥
  const bobPublicKeyImported = await importPublicKey(bobPublicKey);
  const aliceSharedSecret = await deriveSharedSecret(aliceKeyPair.privateKey, bobPublicKeyImported);

  // Bob 使用 Alice 的公钥派生共享密钥
  const alicePublicKeyImported = await importPublicKey(alicePublicKey);
  const bobSharedSecret = await deriveSharedSecret(bobKeyPair.privateKey, alicePublicKeyImported);

  // 验证共享密钥是否相同
  const aliceArray = new Uint8Array(aliceSharedSecret);
  const bobArray = new Uint8Array(bobSharedSecret);
  console.log("Shared secrets match:", arraysEqual(aliceArray, bobArray));
}

function arraysEqual(a, b) {
  if (a.length !== b.length) return false;
  for (let i = 0; i < a.length; i++) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

runECDHExchange();

注意事项

  • 确保使用安全的椭圆曲线(如 P-256、P-384 或 P-521)。
  • 在实际应用中,公钥需要通过安全的方式传输(如 TLS)。
  • 派生出的共享密钥可以用于对称加密(如 AES-GCM)或其他用途。

兼容性

Web Crypto API 在现代浏览器中广泛支持,但在 Node.js 中需要使用 crypto 模块或其他库(如 node-forge)。以下是在 Node.js 中的实现示例:

js ecdh实现

const crypto = require('crypto');

function generateKeyPair() {
  const alice = crypto.createECDH('secp256k1');
  alice.generateKeys();
  const bob = crypto.createECDH('secp256k1');
  bob.generateKeys();

  const aliceSecret = alice.computeSecret(bob.getPublicKey());
  const bobSecret = bob.computeSecret(alice.getPublicKey());

  console.log('Shared secrets match:', aliceSecret.equals(bobSecret));
}

generateKeyPair();

标签: jsecdh
分享给朋友:

相关文章

js实现

js实现

实现 JavaScript 功能的方法 在 JavaScript 中实现特定功能通常涉及多个步骤。以下是常见的实现方法: 基础语法和变量声明 使用 let 或 const 声明变量: let co…

js实现二叉树

js实现二叉树

二叉树的基本概念 二叉树是一种树形数据结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的常见操作包括插入、删除、遍历等。 二叉树的节点定义 在JavaScript中,二叉树的节点可…

js进度条实现

js进度条实现

使用HTML和CSS创建基础结构 在HTML中创建一个容器元素用于显示进度条,通常使用<div>元素。CSS用于设置进度条的样式,包括宽度、高度、颜色和圆角等属性。 <div cl…

js 实现图片 放大

js 实现图片 放大

使用 CSS transform 实现图片放大 通过 CSS 的 transform: scale() 属性可以实现图片的平滑放大效果。结合 JavaScript 监听鼠标事件控制放大状态: con…

js 实现日历

js 实现日历

实现日历的基本思路 日历的核心功能是展示日期,并允许用户进行日期选择或导航。JavaScript 可以动态生成日历的 HTML 结构,并处理用户交互逻辑。 基础日历结构 日历通常包含头部(显示月份和…

js 实现全选

js 实现全选

实现全选功能的方法 使用 JavaScript 实现全选功能通常需要操作复选框(checkbox)的状态。以下是几种常见的实现方式。 通过 DOM 操作实现全选 // 获取全选复选框和子复选框 co…