You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用单个P256密钥对实现ECDSA与ECDH?Rust/Go适配咨询

解决方案

一、继续使用P256曲线(适配Rust WASM + Go互操作)

你偏好纯Rust库且需要适配WASM,无需局限于dalek系列,RustCrypto的p256 crate是纯Rust实现,支持P256曲线的ECDSA签名/密钥生成,且完全兼容Go的crypto/ecdsa。

Rust端实现(纯Rust,支持WASM)

  1. 添加依赖到Cargo.toml:
[dependencies]
p256 = { version = "0.13", features = ["ecdsa", "sha256", "wasm-bindgen"] }
sha2 = "0.10"
  1. 生成密钥对并导出Go可解析的公钥:
use p256::ecdsa::{SigningKey, VerifyingKey};
use p256::pkcs8::EncodePublicKey;
use rand_core::OsRng;

// 生成P256密钥对
let signing_key = SigningKey::random(&mut OsRng);
let verifying_key = VerifyingKey::from(&signing_key);

// 导出公钥为ASN.1 DER格式(Go crypto/ecdsa可直接解析)
let pub_key_der = verifying_key.to_public_key_der().unwrap();
let pub_key_bytes = pub_key_der.as_bytes();

// 将pub_key_bytes发送到Go服务

Go端解析Rust发来的公钥

package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/x509"
	"fmt"
)

func main() {
	// pubKeyBytes 为从Rust接收的DER格式公钥字节
	var pubKey ecdsa.PublicKey
	derBytes := pubKeyBytes // 替换为实际接收的字节
	if err := x509.ParsePKIXPublicKey(derBytes, &pubKey); err != nil {
		panic(err)
	}
	if pubKey.Curve != elliptic.P256() {
		panic("invalid curve")
	}
	// 已完成公钥解析,可用于签名验证等操作
	fmt.Println("Parsed P256 public key:", pubKey)
}

二、切换到ed25519/X25519的方案(签名+密钥交换)

ed25519是签名算法,X25519是对应的ECDH密钥交换算法,不存在同一个密钥对同时支持ed25519签名和ECDH的标准方案,但可以从同一个原始ed25519私钥派生X25519私钥,实现“一套原始密钥,两用”的效果:

Rust端实现

用ed25519-dalek做签名,x25519-dalek做密钥交换:

use ed25519_dalek::{SigningKey, VerifyingKey};
use x25519_dalek::{StaticSecret, PublicKey};
use rand_core::OsRng;

// 生成ed25519密钥对
let ed_signing_key = SigningKey::generate(&mut OsRng);
let ed_verifying_key = VerifyingKey::from(&ed_signing_key);

// 从ed25519私钥派生X25519私钥
let x25519_secret = StaticSecret::from(ed_signing_key.to_bytes());
let x25519_public = PublicKey::from(&x25519_secret);

// 可发送ed25519公钥(签名验证用)或由Go端自行从ed25519公钥派生X25519公钥

Go端实现

Go标准库支持从ed25519密钥派生X25519密钥:

package main

import (
	"crypto/ed25519"
	"crypto/x25519"
	"fmt"
)

func main() {
	// 接收Rust发来的ed25519公钥字节
	edPubKey := ed25519.PublicKey(recvEdPubBytes) // 替换为实际接收的字节
	// 从ed25519公钥派生X25519公钥
	x25519PubKey, err := x25519.Ed25519PublicKeyToX25519(edPubKey)
	if err != nil {
		panic(err)
	}

	// 本地ed25519私钥派生X25519私钥
	edPrivKey := ed25519.PrivateKey(localEdPrivBytes) // 替换为本地私钥
	x25519PrivKey, err := x25519.Ed25519PrivateKeyToX25519(edPrivKey)
	if err != nil {
		panic(err)
	}
	// 用x25519PrivKey与对方x25519PubKey完成ECDH密钥交换
}

内容的提问来源于stack exchange,提问作者mama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 01:47:41