.Net X509Certificate2 (X509 V3) 证书使用(转)
转自:http://blog.csdn.net/greenery/article/details/3942143
.Net 中使用 X509Certificate2 对象进行证书处理。
在 X509Certificate2 对象中,可以访问证书的 ID ,主题,公钥等信息。在 .Net 的 RSA 操作就需要用到这个对象。
证书数据的来源可以是导出的证书文件,本地证书容器,从域中查询用户数据得到。
- 1. 从证书文件获得证书对象。
X509Certificate2 cert = new X509Certificate2 (@"c:/myCert.crt" );
String password = GetCertPassword();
X509Certificate2 cert = new X509Certificate2 (@"c:/myCert.pfx", password);
安全说明: |
不得对源代码中的密码进行硬编码。 使用 MSIL 反汇编程序 (Ildasm.exe) (十六进制编辑器)或直接在文本编辑器(如 Notepad.exe )中打开程序集可以从程序集中检索硬编码密码。 |
- 2. 本地证书容器
X509Store store = new X509Store ("MY" , StoreLocation .CurrentUser);
store.Open(OpenFlags .OpenExistingOnly | OpenFlags .ReadWrite);
//Put certificates from the store into a collection so user can select one.
X509Certificate2Collection fcollection = (X509Certificate2Collection ) store.Certificates;
X509Certificate2Collection collection = X509Certificate2UI .SelectFromCollection (fcollection, "Select an X509 Certificate" , "Choose a certificate to examine." , X509SelectionFlag .SingleSelection);
if (collection.Count > 0)
X509Certificate2 cert = collection[0];
- 3. 从域中查询用户数据得到
DirectoryEntry root = new DirectoryEntry ("LDAP://" + DomainServer, DomainUserName, DomainPassword);
// 检索用户
DirectorySearcher searcher = new DirectorySearcher (root, "CN=" + user);
SearchResult res = searcher.FindOne();
if (res!= null )
{
DirectoryEntry userEntry = res.GetDirectoryEntry();
// 检索证书属性
PropertyValueCollection obj = userEntry.Properties["UserCertificate" ];
if (obj != null)
{
// 当只有一份证书时,对象userCertificate 就是证书的实体
if (obj.Value is byte [])
{
X509Certificate2 cert = new X509Certificate2 ((byte [])obj.Value);
}
// 当用户有多份证书时,userCertificate 是object[] 类型,
// 证书分别保存在object[] 的各个对象中
else if (obj.Value is object [])
{
foreach (object certBuf in (object [])obj.Value)
{
X509Certificate2 cert = new X509Certificate2 ((byte [])certBuf);
}
}
}
}
关于域的更多信息,请参考 DirectoryEntry :
http://technet.microsoft.com/zh-cn/office/system.directoryservices.directoryentry(VS.85).aspx
得到证书后,就可以使用证书进行数字签名、加密、解密数据等操作。但是使用前,要验证证书是否有效。包括:证书链、有效期。
- 1. 证书有效期查检:
if (cert.NotAfter <= DateTime .Now)
{
throw new ApplicationException (" 用户证书已经过期!" );
}
- 证书链查检:
X509Chain ch = new X509Chain ();
ch.ChainPolicy.RevocationMode = X509RevocationMode .Online;
ch.Build(cert);
if (ch.ChainStatus.Length > 0)
{
string msg = " 证书检查错误:/r/n" ;
foreach (X509ChainStatus status in ch.ChainStatus)
{
msg += string .Format("{0}={1}/r/n" , status.Status, status.StatusInformation);
}
throw new ApplicationException (msg);
}
证书链查检是查询证书信息中指定的CRL 地址(证书吊销列表),如果这个地址没法访问,ChainStatus 将返回
RevocationStatusUnknown= 吊销功能无法检查证书的吊销。
OfflineRevocation= 由于吊销服务器已脱机,吊销功能无法检查吊销。
当我们把这个证书颁发站点配置为要求用户验证时,将得到上面的错误。解决方法是把证书颁发站点的 http://yourSite/CertEnroll 配置为匿名访问。