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

如何在Rust中从openssl::pkey::Private类型EcKey提取EC Point的X、Y坐标

从Rust OpenSSL的EcKey中提取公钥X、Y坐标

我来帮你搞定这个问题!其实你不用先把公钥转成压缩字节再手动解析——OpenSSL的Rust绑定已经提供了直接提取坐标的API,既简单又不容易出错。下面是修改后的完整代码,我会一步步解释:

use openssl::bn::{BigNum, BigNumContext};
use openssl::ec::{EcGroup, EcKey, PointConversionForm};
use openssl::nid::Nid;

pub fn exportpubkey(key: &EcKey<openssl::pkey::Private>) {
    // 获取对应的椭圆曲线组(这里是secp256k1)
    let group = EcGroup::from_curve_name(Nid::SECP256K1).unwrap();
    let mut ctx = BigNumContext::new().unwrap();
    
    // 获取公钥对应的点
    let pub_key_point = key.public_key();
    
    // 初始化存储X、Y坐标的BigNum变量
    let mut x = BigNum::new().unwrap();
    let mut y = BigNum::new().unwrap();
    
    // 从公钥点中提取 affine 坐标(X和Y)
    pub_key_point.get_affine_coordinates_gfp(&group, &mut x, &mut y, &mut ctx).unwrap();
    
    // 输出坐标的十六进制格式(也可以转成字节数组)
    println!("X坐标: {}", x.to_hex_str().unwrap());
    println!("Y坐标: {}", y.to_hex_str().unwrap());
    
    // 如果需要字节数组,可以这样做:
    let x_bytes = x.to_vec();
    let y_bytes = y.to_vec();
    println!("X字节: {:?}", x_bytes);
    println!("Y字节: {:?}", y_bytes);
}

关键步骤解释:

  • pub_key_point.get_affine_coordinates_gfp:这个方法是核心,它直接从EC点中提取出对应的X和Y坐标,存储到传入的BigNum变量里。gfp表示我们使用的是有限域上的椭圆曲线(secp256k1就是这类)。
  • 用BigNum处理坐标:因为椭圆曲线的坐标是大整数,BigNum是OpenSSL专门用来处理大数字的类型,支持转十六进制、字节数组等常用格式。

如果你一定要用压缩字节解析(不推荐):

如果坚持要从你已经拿到的压缩字节数组解析,需要注意:

  • 压缩格式的第一个字节是0x02或0x03,表示Y坐标的奇偶性
  • 后面的32字节是X坐标(secp256k1的坐标长度是32字节)
  • Y坐标需要通过椭圆曲线方程y² = x³ + 7(secp256k1的方程)计算出来,还要根据第一个字节确定奇偶性。这种方法需要手动实现域上的平方根计算,容易出错,所以更推荐用上面的API方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:37:44