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

如何在C#(.NET4.7.2)中获取P-384椭圆曲线公钥的未压缩形式

解决方案

下面提供两种适配.NET4.7.2环境的实现方案,分别使用微软内置加密库和Bouncy Castle组件。

方案一:使用微软内置加密库

.NET4.7.2原生支持椭圆曲线加密操作,无需额外引入第三方包。核心逻辑是将Base64公钥解码后导入CngKey,提取公钥坐标后拼接未压缩格式:

using System;
using System.Security.Cryptography;

public static byte[] GetUncompressedP384PublicKey(string base64PublicKey)
{
    // 解码Base64公钥为字节数组
    byte[] publicKeyBytes = Convert.FromBase64String(base64PublicKey);

    // 导入SPKI格式公钥到CngKey
    using (CngKey cngKey = CngKey.Import(publicKeyBytes, CngKeyBlobFormat.SubjectPublicKeyInfo))
    {
        // 创建ECDSA实例并导出公钥参数
        using (ECDSCng ecdsa = new ECDSCng(cngKey))
        {
            ECParameters parameters = ecdsa.ExportParameters(false);
            
            // 拼接未压缩格式:0x04前缀 + X坐标(48字节) + Y坐标(48字节)
            byte[] uncompressedKey = new byte[1 + parameters.Q.X.Length + parameters.Q.Y.Length];
            uncompressedKey[0] = 0x04; // 未压缩格式标识
            Buffer.BlockCopy(parameters.Q.X, 0, uncompressedKey, 1, parameters.Q.X.Length);
            Buffer.BlockCopy(parameters.Q.Y, 0, uncompressedKey, 1 + parameters.Q.X.Length, parameters.Q.Y.Length);
            
            return uncompressedKey;
        }
    }
}

说明

  • 代码默认你的Base64公钥是SPKI格式(X.509 SubjectPublicKeyInfo),这是主流的公钥编码格式
  • 若公钥为裸ECC公钥Blob格式,需将CngKeyBlobFormat.SubjectPublicKeyInfo替换为CngKeyBlobFormat.EccPublicBlob

方案二:使用Bouncy Castle组件

如果内置库无法适配你的公钥格式,可使用Bouncy Castle(需先通过NuGet安装BouncyCastle.Crypto包):

using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto.Parameters;

public static byte[] GetUncompressedP384PublicKeyBouncyCastle(string base64PublicKey)
{
    // 解码Base64公钥
    byte[] publicKeyBytes = Convert.FromBase64String(base64PublicKey);
    
    // 解析ASN.1结构,提取EC公钥参数
    Asn1Object asn1Obj = Asn1Object.FromByteArray(publicKeyBytes);
    SubjectPublicKeyInfo spki = SubjectPublicKeyInfo.GetInstance(asn1Obj);
    ECPublicKeyParameters ecParams = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(spki);
    
    // 获取X、Y坐标字节数组,补全前导零确保长度为48字节(P-384曲线要求)
    byte[] xBytes = ecParams.Q.X.GetEncoded();
    byte[] yBytes = ecParams.Q.Y.GetEncoded();
    
    if (xBytes.Length < 48)
    {
        byte[] paddedX = new byte[48];
        Buffer.BlockCopy(xBytes, 0, paddedX, 48 - xBytes.Length, xBytes.Length);
        xBytes = paddedX;
    }
    if (yBytes.Length < 48)
    {
        byte[] paddedY = new byte[48];
        Buffer.BlockCopy(yBytes, 0, paddedY, 48 - yBytes.Length, yBytes.Length);
        yBytes = paddedY;
    }
    
    // 拼接未压缩格式
    byte[] uncompressedKey = new byte[1 + 48 + 48];
    uncompressedKey[0] = 0x04;
    Buffer.BlockCopy(xBytes, 0, uncompressedKey, 1, 48);
    Buffer.BlockCopy(yBytes, 0, uncompressedKey, 49, 48);
    
    return uncompressedKey;
}

说明

  • Bouncy Castle对多种ASN.1编码格式兼容性更强,能处理更多特殊场景的公钥
  • 代码中强制补全坐标字节长度,确保符合P-384曲线的48字节坐标要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:24:23