将C#证书字符串转换为X509证书

9
我收到一个字符串,想使用C#将其转换为证书。我尝试了以下代码,但出现了“输入不是有效的Base-64字符串,因为它包含一个非Base 64字符、两个以上填充字符或填充字符中的非法字符”错误:
 byte[] bytes = Convert.FromBase64String(((string[])request.Headers.GetValues("MY-Cert"))[0]);
                var cert = new X509Certificate2(bytes);

如何使用C#读取这样的字符串是最好的方法。

类似的问题已经在这里被提出,但是使用的是C++。

我收到的字符串格式如下:

-----BEGIN CERTIFICATE-----
MIIExDCCA6ygAwIBAgIJAK0JmDc/YXWsMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
VQQGEwJJTjELMAkGA1UECBMCQVAxDDAKBgNVBAcTA0hZRDEZMBcGA1UEChMQUm9j
a3dlbGwgY29sbGluczEcMBoGA1UECxMTSW5kaWEgRGVzaWduIENlbnRlcjEOMAwG
A1UEAxMFSU1BQ1MxKTAnBgkqhkiG9w0BCQEWGmJyYWphbkBSb2Nrd2VsbGNvbGxp
bnMuY29tMB4XDTExMDYxNjE0MTQyM1oXDTEyMDYxNTE0MTQyM1owgZwxCzAJBgNV
BAYTAklOMQswCQYDVQQIEwJBUDEMMAoGA1UEBxMDSFlEMRkwFwYDVQQKExBSb2Nr
d2VsbCBjb2xsaW5zMRwwGgYDVQQLExNJbmRpYSBEZXNpZ24gQ2VudGVyMQ4wDAYD
VQQDEwVJTUFDUzEpMCcGCSqGSIb3DQEJARYaYnJhamFuQFJvY2t3ZWxsY29sbGlu
cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDfjHgUAsbXQFkF
hqv8OTHSzuj+8SKGh49wth3UcH9Nk/YOug7ZvI+tnOcrCZdeG2Ot8Y19Wusf59Y7
q61jSbDWt+7u7P0ylWWcQfCE9IHSiJIaKAklMu2qGB8bFSPqDyVJuWSwcSXEb9C2
xJsabfgJr6mpfWjCOKd58wFprf0RF58pWHyBqBOiZ2U20PKhq8gPJo/pEpcnXTY0
x8bw8LZ3SrrIQZ5WntFKdB7McFKG9yFfEhUamTKOffQ2Y+SDEGVDj3eshF6+Fxgj
8plyg3tZPRLSHh5DR42HTc/35LA52BvjRMWYzrs4nf67gf652pgHh0tFMNMTMgZD
rpTkyts9AgMBAAGjggEFMIIBATAdBgNVHQ4EFgQUG0cLBjouoJPM8dQzKUQCZYNY
y8AwgdEGA1UdIwSByTCBxoAUG0cLBjouoJPM8dQzKUQCZYNYy8ChgaKkgZ8wgZwx
CzAJBgNVBAYTAklOMQswCQYDVQQIEwJBUDEMMAoGA1UEBxMDSFlEMRkwFwYDVQQK
ExBSb2Nrd2VsbCBjb2xsaW5zMRwwGgYDVQQLExNJbmRpYSBEZXNpZ24gQ2VudGVy
MQ4wDAYDVQQDEwVJTUFDUzEpMCcGCSqGSIb3DQEJARYaYnJhamFuQFJvY2t3ZWxs
Y29sbGlucy5jb22CCQCtCZg3P2F1rDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
BQUAA4IBAQCyYZxEzn7203no9TdhtKDWOFRwzYvY2kZppQ/EpzF+pzh8LdBOebr+
DLRXNh2NIFaEVV0brpQTI4eh6b5j7QyF2UmA6+44zmku9LzS9DQVKGLhIleB436K
ARoWRqxlEK7TF3TauQfaalGH88ZWoDjqqEP/5oWeQ6pr/RChkCHkBSgq6FfGGSLd
ktgFcF0S9U7Ybii/MD+tWMImK8EE3GGgs876yqX/DDhyfW8DfnNZyl35VF/80j/s
0Lj3F7Po1zsaRbQlhOK5rzRVQA2qnsa4IcQBuYqBWiB6XojPgu9PpRSL7ure7sj6
gRQT0OIU5vXzsmhjqKoZ+dBlh1FpSOX2
-----END CERTIFICATE-----

你是否正在删除 "-----BEGIN CERTIFICATE-----" 前缀(以及匹配的后缀)? - John Wu
@DavidG 不,这篇文章需要证书才能让其他读者理解。SharpCode 只需要为生产使用生成不同的证书即可。 - Andrew Shepherd
这是公共证书。它不包含任何敏感信息,那么你们担心什么,@DavidG,@AndrewShepherd? - Crypt32
不需要解码。PEM标题是自解释的,说明它是不带私钥的公共证书。 - Crypt32
1
@Crypt32,这可能是你在脑海中拥有的技巧,但我们这些凡人不具备... - DavidG
显示剩余2条评论
2个回答

12

以下代码对我有用:

IEnumerable<string> headerValues;
var usercert = request.Headers.TryGetValues("MY-Cert", out headerValues);
var data = WebUtility.UrlDecode(((string[])headerValues)[0]);
byte[] bytes = Encoding.ASCII.GetBytes(data);
var cert = new X509Certificate2(bytes);
              

7
正如评论中指出的那样,您需要从PEM字符串中删除第一行和最后一行,然后将Base64字符串转换为X509Certificate2对象。
String certPemString = ((string[])request.Headers.GetValues("MY-Cert"))[0];
certPemString = certPemString
    .Replace("-----BEGIN CERTIFICATE-----",null)
    .Replace("-----END CERTIFICATE-----",null);
var cert = new X509Certificate2(Convert.FromBase64String(certPemString));

$null是什么?那是语法错误。也许你是想用string.Empty吧? - DavidG
抱歉,那是一个打错的字。已经修正了。 - Crypt32
@Crypt32 给有帮助的答案点赞。但是为了让这段代码工作,我不得不添加 WebUtility.UrlDecode() - SharpCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接