如何在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
相关产品推荐
相关产品推荐

