在.NET 中,X509证书2和 X509证书有什么不同?

这两者有什么区别?

60233 次浏览

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

x509Certificate2是具有附加功能的 x509证书的子类。

  • 它表示实际的 X509证书。
  • 这在.NET Framework v2.0中是新的。
  • 这个类允许您访问所有 V2和 V3属性(权限密钥标识符和密钥使用)。
  • It supports loading a certificate from a certificate store.

为了完整起见,这里有一份 site linked to相关章节的拷贝在@dommer 的回答中,因为这个网站可能不再运行,而且只能在 Google 的缓存中存放不知多久:

框架的1.1版本除了 类,以允许您操作证书 fact, the v1.1 X509Certificate class gave only basic support: it only 允许访问 X509版本1字段(如有效的 from 和 有效的日期,主题和公钥) ,但不是版本2字段(如 权限密钥标识符)或版本3字段(如密钥) 不支持从证书加载证书 存储,也没有访问证书的设施 revocation lists or certificate trust lists. Microsoft improved on 使用 Web 服务增强(WSE)工具包扩展 证书类,并提供用于访问证书存储的类。 这些类现在可以在.NET 3.0/2.0框架库中找到。

第一个较大的变化是一个名为 X509證 icate2的新类 派生自 X509证书。访问 X509的方法 证书字段已被弃用,现在该类已 属性访问这些字段。此外,如果证书具有 一个关联的私钥,然后该类提供对这个密钥的访问权限。 有一些方法允许您提供密码,如果私有 密钥由一个保护。密码通过一个 SecureString 传递 parameter which is a special type that makes sure that when the object 不再被使用的内存,它占用将被写在这样 机器上的其他进程无法读取密码。 安全字符串和其他形式的受保护数据将在 稍后部分。

Since X509Certificate2 derives from X509Certificate it means that you 可以调用静态方法 CreateFromeCertFile 和 通过 X509證 icate2类创建 CreateFromSignedFile, 这些方法返回一个 X509证书对象,您不能关闭 cast this to a X509Certificate2 object. The X509Certificate class has 在版本3.0/2.0中进行了改进: 它提供了访问的属性 一些 X509字段; 它为 从字节数组初始化对象或从 证书,并且它具有将创建对象的构造函数 从一个文件(ASN.1 DER)和从一个字节数组 X509Certificate2 class has a constructor that can create an X509Certificate2 object from an X509Certificate object. Note that 尽管一个 X509证书对象只能显示 X509v1字段 可以从 X509v3证书创建,因此如果创建一个 您将成为来自 X509证书对象的 X509證 icate2对象 能够访问 X509v3字段。

To convert an X.509 cert from "X509Certificate" to "X509Certificate2", try something like this:

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

对于那些希望读取证书并使用该证书进行身份验证的用户,只需创建一个 X509Cericate2并在其构造函数中传递 X509证书。

对于已签名的程序集(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);
}
}

显然你的 class 不叫 MyClass,而是一些你期望从 Web 服务中得到的业务对象。

您可以通过发送您需要填充的属性和值来发送类到您的操作。现在,您可以通过以下方式读取请求证书,以确保您收到的请求来自有效的 Mobile 或 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
}

}

剩下的就是设置你的网络服务器接受客户端证书... 你可以阅读所有来自新格式的属性,你已经保护了你的公共网络服务,一些大多数失败的事情只是被授权不够好了(如果它曾经是)