两者有什么区别?
4 回答
为了完整起见,这里是@dommer 的答案中链接到的站点相关部分的副本,因为该站点可能不再启动,并且仅在 Google 的缓存中存在不知道多长时间:
除了 X509Certificate 类之外,该框架的 1.1 版几乎没有允许您操作证书。事实上,v1.1 X509Certificate 类只提供了基本支持:它只提供了对 X509 版本 1 字段(如有效起始日期和有效截止日期、主题和公钥)的访问权限,而不是版本 2 字段(如授权密钥标识符) ) 也不是版本 3 字段(如密钥用法)。不支持从证书存储加载证书,也没有访问证书吊销列表或证书信任列表的工具。Microsoft 通过扩展证书类并提供访问证书存储的类的 Web 服务增强 (WSE) 工具包对此进行了改进。现在可以在 .NET 3.0/2.0 框架库中找到这些类。
第一个重大变化是一个名为 X509Certificate2 的新类,它派生自 X509Certificate。访问 X509 证书字段的方法已被弃用,现在该类具有访问这些字段的属性。此外,如果证书具有关联的私钥,则该类授予对该密钥的访问权限。如果私钥受密码保护,则有一些方法允许您提供密码。密码通过 SecureString 参数传递,该参数是一种特殊类型,可确保当不再使用对象时,它占用的内存将被覆盖,这样机器上的另一个进程就无法读取密码。安全字符串和其他形式的受保护数据将在后面的部分中介绍。
由于 X509Certificate2 派生自 X509Certificate 这意味着您可以通过 X509Certificate2 类调用静态方法 CreateFromeCertFile 和 CreateFromSignedFile。但是,这些方法返回一个 X509Certificate 对象,您不能将其向下转换为 X509Certificate2 对象。X509Certificate 类在 3.0/2.0 版本中得到了改进:它提供了访问某些 X509 字段的属性;它提供 Import 和 Export 方法来从字节数组初始化对象或从证书生成字节数组,并且它具有将从文件 (ASN.1 DER) 和字节数组创建对象的构造函数。有趣的是,X509Certificate2 类有一个构造函数,可以从 X509Certificate 对象创建 X509Certificate2 对象。
要将 X.509 证书从“X509Certificate”转换为“X509Certificate2”,请尝试以下操作:
X509Certificate X509 = sslStream.RemoteCertificate;
X509Certificate2 X5092 = new X509Certificate2(X509);
对于那些想要阅读证书并使用它来进行身份验证的人来说,只需创建一个 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
}
}
剩下的就是将您的网络服务器设置为接受客户端证书......您可以阅读所有来自新格式的属性并且您已经保护了您的公共网络服务,大多数都无法做到,因为仅仅获得授权还不够好不再(如果曾经)