.NET 中的 X509Certificate2 和 X509Certificate 有啥区别?

Posted

技术标签:

【中文标题】.NET 中的 X509Certificate2 和 X509Certificate 有啥区别?【英文标题】:What is the difference between X509Certificate2 and X509Certificate in .NET?.NET 中的 X509Certificate2 和 X509Certificate 有什么区别? 【发布时间】:2010-11-14 00:48:49 【问题描述】:

两者有什么区别?

【问题讨论】:

【参考方案1】:

x509Certificate 是在 .NET v1.0/1.1 中引入的,并且(相对而言)其功能受到限制。 它可用于获取有关现有证书的信息(有效日期、颁发者等)。它有简单的方法/操作(即从磁盘读取证书)。

x509Certificate2 是 x509Certificate 的子类,具有附加功能。

它代表一个实际的 X509 证书。 它是 .NET Framework v2.0 中的新功能。 该类使您可以访问所有 V2 和 V3 属性(授权密钥标识符和密钥用法)。 它支持从证书存储加载证书。

【讨论】:

X509Certificate2 也有一个私钥成员,它不是证书本身的一部分,但可以方便地与代表 X.509 证书的类关联。【参考方案2】:

为了完整起见,这里是@dommer 回答中site linked to 相关部分的副本,因为该站点可能不再启动,并且仅在谷歌的缓存中不知道多长时间:

框架的 1.1 版除了 X509Certificate 类允许您操作证书。在 事实上,v1.1 X509Certificate 类只提供了基本支持:它只 允许访问 X509 版本 1 字段(例如有效的 from 和 对日期、主题和公钥有效)但不是版本 2 字段(如 授权密钥标识符)或版本 3 字段(如密钥 用法)。不支持从证书加载证书 存储,也没有访问证书的设施 吊销列表或证书信任列表。微软改进了 这与扩展了 Web 服务增强 (WSE) 工具包 证书类和提供类来访问证书存储。 现在可以在 .NET 3.0/2.0 框架库中找到这些类。

第一个重大变化是一个名为 X509Certificate2 的新类,它 源自 X509Certificate。 X509的访问方法 证书字段已被弃用,现在该类已 属性来访问这些字段。此外,如果证书有 一个关联的私钥,然后该类可以访问该密钥。 有一些方法可以让您提供密码,如果私人 密钥受一个保护。密码通过 SecureString 传递 参数是一种特殊类型,可确保当对象 不再使用它占用的内存将被覆盖所以 密码不能被机器上的另一个进程读取。 安全字符串和其他形式的受保护数据将包含在 后面的部分。

由于 X509Certificate2 派生自 X509Certificate 这意味着您 可以调用静态方法 CreateFromeCertFile 和 CreateFromSignedFile 通过 X509Certificate2 类。然而, 这些方法返回一个 X509Certificate 对象,您无法关闭 将此转换为 X509Certificate2 对象。 X509Certificate 类有 在 3.0/2.0 版本中进行了改进:它提供了可以访问的属性 一些 X509 字段;它提供了 Import 和 Export 方法 从字节数组初始化对象或生成字节数组 证书,它具有将创建对象的构造函数 来自文件(ASN.1 DER)和字节数组。有趣的是, X509Certificate2 类有一个构造函数,可以创建一个 X509Certificate 对象中的 X509Certificate2 对象。注意 尽管 X509Certificate 对象只能显示它的 X509v1 字段 可以从 X509v3 证书创建,因此如果您创建一个 您将成为 X509Certificate 对象中的 X509Certificate2 对象 能够访问 X509v3 字段。

【讨论】:

【参考方案3】:

要将 X.509 证书从“X509Certificate”转换为“X509Certificate2”,请尝试以下操作:

X509Certificate  X509  = sslStream.RemoteCertificate;
X509Certificate2 X5092 = new X509Certificate2(X509);

【讨论】:

【参考方案4】:

对于那些想要读取证书并使用它进行身份验证的人,只需创建一个 X509Certificate2 并在其构造函数中传递 X509Certificate。

对于已签名的程序集(exe),代码将是这样的代码,为简单起见,我省略了错误验证。

Module m = Assembly.GetEntryAssembly().GetModules()[0];
using (var cert = m.GetSignerCertificate())
using (var cert2 = new X509Certificate2(cert))

   var _clientHandler = new HttpClientHandler();
   _clientHandler.ClientCertificates.Add(cert2);
   _clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
   var myModel = new Dictionary<string, string>
   
        "property1","value" ,
        "property2","value" ,
   ;
   using (var content = new FormUrlEncodedContent(myModel))
   using (var _client = new HttpClient(_clientHandler))
   using (HttpResponseMessage response = _client.PostAsync($"url/controler/action", content).Result)
   
       response.EnsureSuccessStatusCode();
       string jsonString = response.Content.ReadAsStringAsync().Result;
       var json = new Newtonsoft.Json.JsonSerializer();
       var myClass = JsonConvert.DeserializeObject<MyClass>(json);
    

显然,您的类不称为 MyClass,而是您期望从 Web 服务获得的一些业务对象。

您可以通过发送您需要填写的属性和值来向您的操作发送一个类。您现在可以通过读取请求证书来确保您收到的请求来自有效的移动或 Windows 客户端,如下所示:

public class MyController : ApiController

    public IHttpActionResult Get()
               
       X509Certificate2 clientCertInRequest = Request.HttpContext.Connection.ClientCertificate;
       if (!clientCertInRequest.Verify() || !AllowedCerialNumbers(clientCertInRequest.SerialNumber))
       
            Response.StatusCode = 404;
            return null;
       
       //your code
   

剩下的就是将您的网络服务器设置为接受客户端证书...您可以阅读所有来自新格式的属性并且您已经保护了您的公共网络服务,因为只是获得授权,所以大多数人都无法做到这一点。已经不够好了(如果有的话)

【讨论】:

以上是关于.NET 中的 X509Certificate2 和 X509Certificate 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

如何在.net 中创建一个全新的 x509Certificate2?

如何以编程方式创建有效的自签名 X509Certificate2,而不是从 .NET Core 中的文件加载

X509Certificate2 使 IIS 崩溃

获取 X509Certificate2 私钥和公钥

使用 ASP.NET Core 3.0 内置 API 从 .crt 和 .key 文件创建 X509Certificate2

x509certificate2 中的空 PrivateKey