在我用解析器解码你的公钥之后here http://lapo.it/asn1js/#MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkxqnUqh5WYis_Q-sQc5hO9i5aX7XvVEVdrhrnFcbwSb1_GyQWPvn1ZydQB88zW9CnNFq08QRg-IYaBYdqs12EbxkET20eWY7xvI8kBICPxOdYAHBb0JWpdK4GjSCSxCFrJIXXmHtnRqj6PmSoPrbuFdC5MTFXfFwphgZi-Ae5MM2nxDu0P_UT8W1VMNVYRkC0dldo-csK1p9NLKga64zMiNop9nM3meSHpOt-P65l1B-e5EeXM-qzrIeJH4ul95HJdKkPypDM18y4FkFA73Sr6vHYQvQjmBiGy0op1Qs7t-8UkpOX41j28IeiE2yyG7S6_k8Qcu0yv1uaFn3a9VJjwIDAQAB,我可以看到这是一个完全形成的 ANS.1 密钥。您链接到的帖子中的解决方案有效......但对于不完整的密钥。我很惭愧地说我在发布的答案中遗漏了一条重要的信息 - 之后我将更新相关信息。
所以。简而言之,我无法正确解码完整形成的公钥 - 我必须按字节提取。我们仍在等待 MS 的 ASN 解析逻辑公开(看起来在 3.0 推出时暂停了)。在我的情况下,我可以控制公钥的导出方式,因此我能够控制如何在 PEM 中创建公钥 blob。
如果您自己就是这种情况,请将公钥 + 私钥对加载到RSACryptoServiceProvider
然后像这样导出它;
var cert = new X509Certificate2(keypairBytes, password,
X509KeyStorageFlags.Exportable
| X509KeyStorageFlags.MachineKeySet);
var partialAsnBlockWithPublicKey = cert.GetPublicKey();
// export bytes to PEM format
var base64Encoded = Convert.ToBase64String(partialAsnBlockWithPublicKey, Base64FormattingOptions.InsertLineBreaks);
var pemHeader = "-----BEGIN PUBLIC KEY-----";
var pemFooter = "-----END PUBLIC KEY-----";
var pemFull = string.Format("{0}\r\n{1}\r\n{2}", pemHeader, base64Encoded, pemFooter);
如果您从此密钥创建 PEM,您将能够使用链接问题中描述的方法将其加载回来。为什么会有所不同?对 cert.GetPublicKey() 的调用实际上会返回 ASN.1 块结构;
SEQUENCE(2 elem)
INTEGER (2048 bit)
INTEGER 65537
这实际上是一个不完整的 DER blob,但 .NET 可以解码(在撰写本文时 .NET 不支持完整的 ASN.1 解析和生成 -https://github.com/dotnet/designs/issues/11 https://github.com/dotnet/designs/issues/11).
正确的 DER (ASN.1) 编码公钥字节具有以下结构;
SEQUENCE(2 elem)
SEQUENCE(2 elem)
OBJECT IDENTIFIER "1.2.840.113549.1.1.1" - rsaEncryption(PKCS #1)
NULL
BIT STRING(1 elem)
SEQUENCE(2 elem)
INTEGER (2048 bit)
INTEGER 65537
好的,上面的内容为您提供了一个可以加载的公钥(某种形式)。怎么带回来?来自链接答案的复制/粘贴(假设您再次获得了文件字节);
const string rsaOid = "1.2.840.113549.1.1.1"; // found under System.Security.Cryptography.CngLightup.RsaOid but it's marked as private
Oid oid = new Oid(rsaOid);
AsnEncodedData keyValue = new AsnEncodedData(publicKeyBytes); // see question
AsnEncodedData keyParam = new AsnEncodedData(new byte[] { 05, 00 }); // ASN.1 code for NULL
PublicKey pubKeyRdr = new PublicKey(oid, keyParam, keyValue);
var rsaCryptoServiceProvider = (RSACryptoServiceProvider)pubKeyRdr.Key;
以上应该让您进入工作状态。