2012-04-20 24 views
3

我想开发一个ASP.net网站读取则ClientCertificate,以确保智能卡来访问网站(试图用用户名/密码登录做掉)。智能卡安全性,您如何认证证书不是假的?

的过程中,我在我的脑海是:

  1. 用户注册一个账号和C#记录用户的clientCertificate(公共)。然后
  2. 用户可以登录与同一clientCertificate接下来的时间,而他们现在的身份验证的用户,如果哈希有效。
  3. 我将使用下面的代码,以确保证书的真实性。浏览器应该处理私钥并确保证书不被伪造。
  4. 基于Subject +证书组合,C#为他们分配角色访问权限。

以下代码可被用于权证书真伪?

X509Certificate x509Cert = new X509Certificate(Request.ClientCertificate.Certificate); 
SHA1 sha = new SHA1CryptoServiceProvider(); 
byte[] hashvalue = sha.ComputeHash(Request.ClientCertificate.Certificate); 
byte[] x509Hash = x509Cert.GetCertHash(); 
// compare x509Hash WITH hashvalue to ensure they are a match. 
// If not, possibly faked certificate, not a real smartcard??? 

这是认证过程中应如何智能卡工作???

回答

2

如果你只是需要验证你应该在IIS做这个客户端证书的用户。除非你需要客户端证书与数据库帐户链接或执行额外的验证步骤

Specify Whether to Use Client Certificates (IIS 7)

:你并不需要在所有添加任何代码到你的应用程序。但仍然为客户端证书身份验证,我会坚持使用IIS设置。

更新: 如果你需要操作的客户端证书,你可以这样做:

X509Certificate2 x509Cert2 = new X509Certificate2(Page.Request.ClientCertificate.Certificate); 

,然后访问它的属性,如:

x509Cert2.Subject 

然而,离开了验证件直到IIS。如果客户提出了一个坏的证书您的asp.net的代码,因为IIS甚至不会执行会拒绝它

+0

是的,我将客户端证书(智能卡)与具有更高特权的数据库帐户连接起来。我必须100%确定,智能卡实际上属于他们,而不仅仅是具有相同公钥的复制或伪造证书。 – Dexter 2012-04-20 15:41:03

+0

好的,在这种情况下,使用Page.Request.ClientCertificate.Certificate获取请求证书对象(X509Certificate2)的属性,例如“x509Cert2.Subject”。但是,将验证片留给IIS。如果客户端提交了一个错误的证书,你的asp.net代码甚至不会执行,因为IIS会拒绝它。 – Ulises 2012-04-20 15:45:19

+0

那么我的代码是正确的呢?我只是检查散列和证书是否有效(certificate.IsValid),并且可能将其放在try {} catch {}中,这足以确保该人拥有正确的智能卡?捕获将触发,我可以通过登录失败,因为代码无法获取证书(因为它是假的)。 – Dexter 2012-04-20 15:50:36

2

看到这个线程,先生。您不需要在代码中明确验证真实性。 IIS会为你做。

Does IIS do the SSL certificate check or do I have to verify it?

IIS甚至试图检查吊销列表(但是,如果CRL大,这是经常被禁用)。如果CRL非常大或者检查延迟很高,应使用OCSP应答器进行验证http://www.axway.com/products-solutions/email-identity-security/identity-security/va-suite

+0

所以在C#代码,当我抢Request.ClientCertificate.Certificate和Request.ClientCertificate.Subject - 这是保证这个人不只是使人的智能卡证书的副本,并复制公钥? (换句话说,IIS将确保Request.ClientCertificate.Certificate每次都是唯一且真实的)? – Dexter 2012-04-20 15:43:48

+0

IIS将帮助您确保提供的证书有效。顺便说一下,公钥是公开的。每个人都可以拥有它:http://en.wikipedia。org/wiki/Secure_Socket_Layer – Ulises 2012-04-20 16:00:13

+0

是的,当然,这是我的观点。如果我在代码中检查公钥,以此来确定该用户是否真正是在我的代码和数据库中注册的用户 - 那么这是一个安全漏洞,因为公共密钥是公开给所有人的。我想知道我是否需要privatekey-publickey-combo检查来确保真实性。 – Dexter 2012-04-20 16:14:09

1

客户端证书认证的SSL/TLS握手期间完成。

它通常使用公钥基础结构完成,服务器拥有一个(固定的)可信CA证书列表,用于验证客户端证书(与客户端验证服务器的方式相同)。一旦证书也到这个阶段之后你的应用程序,你会知道:

  • 客户拥有该证书的私钥(由TLS handhsake的Certificate Verify message(在SSL保证/ TLS协议栈会验证这一点对你来说,没有必要实施任何东西);
  • 的客户端证书中描述的身份,因为你已经验证这对你的信任的CA

对信任的CA验证需要用户请提前向该CA注册。如果我不能验证任何证书, t并未由您信任的CA颁发。 (将证书的主题映射到本地用户标识是另一回事:例如,如果需要,可以在第一次连接时执行此操作:例如,使用自己的数据库或目录服务将主题DN映射到应用程序中的另一种用户标识。

用户注册一个帐户,C#记录用户的客户端证书 (公共)。然后,用户可以使用相同的 clientCertificate登录,如果hash 有效,则它们现在是经过身份验证的用户。

这听起来像你想允许任何证书将呈现和使用它的初始登记,而不必诉诸普遍信任的CA.

原则上这是可能的,我已经完成了这项工作来探索Java中PKI的替代方案。

要做到这一点,您需要让任何证书通过SSL/TLS握手,稍后再验证证书。 (您需要使用某种形式的验证。)您仍然保证,客户端拥有它提供的公钥证书的私钥。

这样做需要两个步骤:

  • 您需要能够来宣传你会接受任何证书事实上,在Certificate Request TLS消息发送证书颁发机构的空单(明确由TLS 1.1允许)。
  • 配置SSL/TLS堆栈信任任何证书(再次,当你做到这一点,不要忘了你的应用程序中实现自己的验证系统,否则很少会真正得到通过)。

在.NET中,而应该尽可能使用remote certificate validation callback解决第二点,我从来没有找到一种方法来改变第一点(这也被要求在this question)。

在Java中,JSSE的X509TrustManager允许您解决这两个问题。

+0

不,我只允许拥有我正在寻找的智能卡类型的用户访问系统。我想我必须联系证书颁发机构,申请一个服务器证书,然后“完成”证书请求,然后将其插入系统,然后才能开始允许客户端向服务器数据库注册他们的Clientcertificates。我猜我必须使用try/catch来检查用户是否输入了有效的证书,否则当他们有一个无效的私钥时会弹出一个错误。 – Dexter 2012-04-20 17:30:17

+0

拥有相同类型的智能卡并不意味着您的所有用户都拥有来自同一CA的证书。 (例如,如果它们是由您的环境中的CA提供的)。您的服务器证书不一定来自您将接受客户端证书的CA之一(它是相当独立的)。您甚至不需要尝试/捕获:如果用户提供了您未配置的CA识别的证书,则甚至不会建立SSL/TLS连接(因此不会建立HTTP(S)连接)。从UI的角度来看,它在浏览器中看起来像是'ssl_error_blablabla'。 – Bruno 2012-04-20 17:46:20

+0

现在我正在我的开发环境中使用自签名服务器证书进行测试,并且只是读取客户端证书(不管我没有检查任何CA),所以它总是说SSL错误,但它允许您进入网站。当我将其转换为X509Certificate2时,如果您更改证书的字节并尝试计算散列,则会抛出CryptographyException。所以这个例外可以让你知道这个证书是否有什么腥意。这是您的服务器端代码可以确保真实性的一种方式(否则您需要验证客户端证书撤销和一些IIS设置 – Dexter 2012-04-20 18:59:10