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

从X509Certificate2生成的十六进制字符串还原RSA公钥失败

数字签名项目公钥转换与解密问题

开发数字签名项目时,获取到通过X509Certificate2.GetPublicKeyString()生成的十六进制公钥字符串:

3082010A0282010100D8F165280738A827AA1D2960D09ECA7EA3928BC3B6BA4CF034BEFE6E00DB434793B96C2FD2411BE086B6CE4B30441D18DFF377497F99F043E74B2C30555D2157C2838C9E7BDD566F0633CC0BE6F2649278BB8FE15EB2D4020C087B2252D8ED024DD260A3AA07F399D90EBDA722BEFECAD6D7A011A30F9013C4AFE3E15BA5E5B9028DE51079CDE125555B82E4269699E662D8BF182DF173FCC90135FC117B8254BF7036FE0A9B0667C0266E8EF94F9EE630CA0CF611FF0BB2BBFD99A7B9D9CC6C93D272A7DC87FE59D35C34D9487F1038179C6576114994C942F826168BDF112DD17FC5725684AE74359FED8C753D1D7F01AB8F5A070E93DD89CA0C9BC2520C850203010001

尝试通过以下代码将其转换为PEM格式:

byte[] certBytes = Enumerable.Range(0, certHex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(certHex.Substring(x, 2), 16))
                     .ToArray();
string certPem = "-----BEGIN RSA PUBLIC KEY-----\n" +
    Convert.ToBase64String(certBytes, Base64FormattingOptions.InsertLineBreaks)
    .TrimEnd() + "\n-----END RSA PUBLIC KEY-----\n";

生成的PEM如下(实际生成时错误使用了CERTIFICATE标签):

-----BEGIN CERTIFICATE-----
MIIBCgKCAQEA2PFlKAc4qCeqHSlg0J7KfqOSi8O2ukzwNL7+bgDbQ0eTuWwv0kEb4Ia2zkswRB0Y
3/N3SX+Z8EPnSywwVV0hV8KDjJ573VZvBjPMC+byZJJ4u4/hXrLUAgwIeyJS2O0CTdJgo6oH85nZ
Dr2nIr7+ytbXoBGjD5ATxK/j4Vul5bkCjeUQec3hJVVbguQmlpnmYti/GC3xc/zJATX8EXuCVL9w
Nv4KmwZnwCZujvlPnuYwygz2Ef8Lsrv9mae52cxsk9Jyp9yH/lnTXDTZSH8QOBecZXYRSZTJQvgm
FovfES3Rf8VyVoSudDWf7Yx1PR1/AauPWgcOk92JygybwlIMhQIDAQAB
-----END CERTIFICATE-----

遇到的问题:

  1. 执行X509Certificate2 cert = new X509Certificate2(Encoding.ASCII.GetBytes(certPem));时加载失败
  2. 使用以下解密逻辑时,调用Decrypt抛出异常:Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'Key does not exist.'
csp = RSA.Create();
csp.ImportFromPem(certPem.ToCharArray());
var decryptedBytes = csp.Decrypt(encryptedData, RSAEncryptionPadding.Pkcs1);

解决思路

  • 修正PEM标签:X509Certificate2.GetPublicKeyString()返回的是SubjectPublicKeyInfo格式的ASN.1 DER编码,对应的PEM标签应为-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----,而非RSA PUBLIC KEY或CERTIFICATE(后者用于完整证书,不是单独公钥)。
  • 修正转换代码:调整PEM首尾标签,代码示例:
byte[] certBytes = Enumerable.Range(0, certHex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(certHex.Substring(x, 2), 16))
                     .ToArray();
string certPem = "-----BEGIN PUBLIC KEY-----\n" +
    Convert.ToBase64String(certBytes, Base64FormattingOptions.InsertLineBreaks)
    .TrimEnd() + "\n-----END PUBLIC KEY-----\n";
  • 正确加载公钥:修正后的PEM可被RSA.ImportFromPem正确识别,无需手动拆分指数和模数(SubjectPublicKeyInfo已包含算法标识和完整公钥结构)。
  • X509Certificate2加载问题说明:该类用于加载完整的X.509证书,而你只有公钥数据,因此不能用它加载,直接使用RSA类处理公钥即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:05:18