从 C# 中的 x509 证书字节读取 RSA Public 密钥

Read RSA Public Key from x509 Certificate Bytes in C#

在 C# 中,我从 HTTP 请求中检索 RSA public 密钥,它为我提供了以 base64 编码的密钥。

WebClient webClient = new WebClient();
string rsaPublicKeyBase64 = webClient.DownloadString("http://localhost:8000/getkey");
// rsaPublicKeyBase64 = LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FEdDAwcXQ2Zi9UUXdMQmVsVExRdVlXb05xSQoxbmRkcFpaOGh0WWs4d0NLbmFuRFJpWkJ1NVo5NnBNT01yNi84RS9JUzB0amV4WGdsVjh0WFlKK0NKc1lDUHhoCnBDUkduUW9rYkE2MnpOODVXNEROVUNMQ0cyMXlXcndscFhjSmxLYkY2dFhxdmd3TGRQb2RwZzUwY3RrWkI4R0UKbDBLS3VOV3JHZXRad045V0NRSURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=

然后我解码 base 64 RSA public 密钥。

byte[] rsaPublicKey = Convert.FromBase64String(rsaPublicKeyBase64);
/*
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDt00qt6f/TQwLBelTLQuYWoNqI
1nddpZZ8htYk8wCKnanDRiZBu5Z96pMOMr6/8E/IS0tjexXglV8tXYJ+CJsYCPxh
pCRGnQokbA62zN85W4DNUCLCG21yWrwlpXcJlKbF6tXqvgwLdPodpg50ctkZB8GE
l0KKuNWrGetZwN9WCQIDAQAB
-----END PUBLIC KEY-----
*/

我的下一步是将包含我的 RSA public 密钥证书的 byte[] 转换为 RSACryptoServiceProvider 类型。我在网上找到了答案,但 none 似乎对我有用。

这是我目前拥有的(不起作用)。

string rsaPublicKeyFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
X509Certificate2 cert = null;
try {
    File.WriteAllBytes(rsaPublicKeyFile, rsaPublicKey);
    cert = new X509Certificate2(rsaPublicKeyFile);
} finally {
    File.Delete(rsaPublicKeyFile);
}

我收到一个未处理的异常错误,如下面的屏幕截图所示。

System.Security.Cryptography.CryptographicException: 'Cannot find the requested object.

感谢@Crypt32,我参考PublicKey Class documentation

设法解决了这个问题

我写了一个函数GetCertificateFromBytes(byte[] cert),它写入临时文件以读取证书:

public static X509Certificate2 GetCertificateFromBytes(byte[] cert) {
    string certFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
    try {
        File.WriteAllBytes(certFile, cert);

        X509Store store = new X509Store(StoreLocation.CurrentUser);
        try {
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certCollection = store.Certificates;
            return certCollection[0];
        } finally {
            store.Close();
        }
    } finally {
        File.Delete(certFile);
    }
}

然后加密:

X509Certificate2 cert = GetCertificateFromBytes(rsaPublicKey);
RSACryptoServiceProvider publicKeyProvider = (RSACryptoServiceProvider)cert.PublicKey.Key;
byte[] encrypted = publicKeyProvider.Encrypt(data, false);