1数字证书登录认证的优点

作为企业信息系统的第一道大门,身份认证是确保企业信息资源只能被合法用户所访问的重要保障。
传统的口令认证方式虽然简单,但是由于其易受到窃听、重放等攻击的安全缺陷,使其已无法满足当前复杂网络环境下的安全认证需求。
传统账号+口令登录的弊端:
1.         口令易被猜测。由于有的用户为了方便记忆,使用非常简单的口令,比如“1234”、“abcd”等这些非常容易被猜测的口令。
2.         口令易被窃听。大家都知道,WEB应用在互联网上是基于TCP/IP协议的,该协议本身并不负责数据传输的安全性,用户口令在互联网上的传输,需要经过很多个网络节点(比如路由器),可以在这任意一个网络节点去窃听到用户的口令。
3.         口令记忆麻烦。用户在不同的WEB应用上建立不同的帐户,需要记忆不同的口令,记忆这么多的口令形成用户很大的负担,于是有的用户把不同WEB应用的口令设置成相同的口令,这样又引入了新的安全隐患,只需破解用户的一个WEB口令,就等于破解了该用户别的WEB应用口令。
4.         可以从服务器攻击客户口令。WEB应用服务上,由于需要校验用户的口令,所以需要保留用户的口令或口令的摘要值。若这个用户口令表被黑客非法获取,整个WEB应用的用户认证将形同虚设。
5.         无法确定用户的真实身份。正因为口令的脆弱性,使得口令很容易被窃用。

随着PKI技术体系的成熟,拥有强有力的理论基础和众多国际标准的CA数字证书身份认证技术,在法律上得到了国家的大力支持。电子签名法的颁布实施以及数字加密和数字签名技术所具有的保密性、完整性、真实性、不可否认性等特点,使得CA数字证书身份认证正在被广泛采用。

作为个人数字证书及其对应私钥的存储介质的USBkey、IC卡等,在此统称为eKey(电子密钥),自带CPU,内嵌加密算法,可进行加密运算,其中的私密信息不可复制。因此,eKey以其安全可靠、易于携带、使用方便、成本低廉、性价比高等特点,在身份认证领域也正发挥着越来越多的作用,成为身份认证技术的一个重要发展方向和趋势。
引进eKey+数字证书登录带来的好处:
1.         安全。双因子认证。用户在使用eKey之前,需要输入PIN码验证;验证通过后再调用eKey里的私钥作用于身份认证用的签名运算。这样就等于设置了2道门,都通过后才能最终进入。
2.         方便。用户只需随身携带一个eKey,就可不限时间、不限地点的证明自己的身份。可以用同一个eKey登录不同的Web站点而不怕安全问题。
3.         用户身份具有法律保障。用户的数字证书由权威的CA签发。用户的登录认证可以保留日志用于以后追溯,即可防伪造又可防抵赖。
2身份认证原理
2.1数字签名
数字签名的产生和验证过程:
1.         Alice产生文件的单向散列值。
2.         Alice用她的私人密钥对散列加密,以此表示对文件的签名。
3.         Alice将文件和散列签名送给Bob。
4.         Bob用Alice发送的文件产生文件的单向散列值,同时用Alice的公钥对签名的散列解密。如果签名的散列值与自己产生的散列值匹配,签名是有效的。
数字签名具有以下特性:
1.         完整性。因为它提供了一项用以确认电子文件完整性的技术和方法,可认定文件为未经更改的原件。
2.         可验证性。可以确认电子文件之来源.由于发件人以私钥产生的电子签章惟有与发件人的私钥对应的公钥方能解密,故可确认文件之来源。
3.         不可否认性。由于只有发文者拥有私钥,所以其无法否认该电子文件非由其所发送。

2.2身份认证
流程如下:

在实际的部署中,认证服务器的功能可以在应用服务器实现。
步骤说明:
1.         浏览器打开应用登录页面,里面包含一个被签名的随机数,随机数在应用服务器端产生,记作RS
2.         浏览器调用Ekey对RS进行签名
3.         Ekey返回对RS的签名,记作SS2_C(RS)
4.         浏览器提交表单,里面包含用户证书SCertC和签名SS2_C(RS),并用PKCS#7的SignedData封装
5.         应用服务器把RS和SignedData交给认证服务器验证
6.         认证服务器解开SignedData里面的签名内容、用户证书和数据签名,比较签名内容是否和RS相同,证书是否有效,签名是否有效,若都有效,再查询该证书对应的用户ID。返回验证成功消息及用户账号
7.         应用服务器返回登录成功页面,给以该用户账号使用应用服务
该流程的优点是:
l         挑战-响应机制:客户端在发起认证请求时,服务器端首先产生并返回一个随机数(挑战);客户端在提交认证请求时,将数字签名后的随机数发送到服务器端(响应),由服务器端比较本地的随机数和收到的随机数,以校验认证请求的有效性,从而有效防止截获和重放攻击。
l         数字签名机制:客户端提交的认证请求,均由客户端认证组件调用eKey进行签名处理。eKey随身携带,其中的私钥不可复制,保证了私钥的唯一性,由于数字签名不可伪造和篡改,服务器端通过校验客户端用户证书和数字签名的有效性,并结合认证数据库鉴别用户身份。

3数字证书登录认证的实现
以下讨论如何实现数字证书在Web应用中作登录认证。
 
3.1SSL方式
SSL在握手过程中,服务端接受客户端证书
SSL的用户端认证:

CertificateRequest消息指示客户端要进行客户端认证,并就服务器愿意接受的认证类型提供指导:
struct{
       ClientCertificateType certificate_types<1..2^8-1>;
       DistinguishedName certificate_authorities<3..2^16-1>;
}CertificateRequest;
enmu{
       rsa_sign(1),dss_sign(2),rsa_fixed_db(3),dss_fixed_dh(4),
       (255)
}ClientCertificateType;
opaque DistinguishedName<1..2^16-1>;
certificate_types指示支持哪种类型的客户端证书。certificate_authorities指示服务器愿意接受哪些CA签发的客户端证书。
Certificate消息是客户端向服务端提交的表明身份的数字证书链,证书链的第一个证书就是表明用户身份的数字证书。
struct{
       ASN.1Cert certificate_list<1..2^4-1>
}Certificate;

opaque ASN.1Cert<2^24-1>;
CertificateVerify消息用于真正的客户端认证。它包含由客户端私钥签名的消息,签名内容为自ClientHello到本消息(不包含本消息)所收发的所有握手消息。且由于这些握手消息带有导出主密钥(master_secret)的随机数,所以本消息可以防止被重放。
struct {
       Signature signature;
} CertificateVerify;
select (SignatureAlgorithm)
{
       case anonymous: struct { };
       case rsa:
              digitally-signed struct {
                     opaque md5_hash[16];
                     opaque sha_hash[20];
              };
       case dsa:
              digitally-signed struct {
                     opaque sha_hash[20];
              };
} Signature;
CertificateVerify.signature.md5_hash=MD5(handshake_messages);
CertificateVerify.signature.sha_hash=SHA(handshake_messages);
 

3.1.1WEB服务器设置
WEB服务器设置成需要客户端认证。
iis
需要首先在服务端和客户端都安装CA证书链,可以通过MMC控制台对计算机帐户受信任根证书进行添加

tomcat
需要首先在服务端和客户端都安装CA证书链,可以在JDK目录下的cacerts进行添加
修改c:/tomcat/conf/server.xml,添加如下内容:
<Connector port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="c:/server_keystore"
keystorePass="changeit"
truststoreFile="c:/trustcacerts_keystore"
truststorePass="changeit"
/>
 
3.1.2得到客户端证书
当WEB服务器设置成需要客户端认证时,客户端在建立SSL链接时会提交用户证书链,证书链的第一个即是表明用户身份的个人证书。
j2ee

<%@ page import="java.security.cert.X509Certificate" %>
 
<%
if(request.isSecure())     //判断是否采用SSL
{
       final String attname= "javax.servlet.request.X509Certificate";
       X509Certificate[] chain= (X509Certificate[])request.getAttribute(attname);//客户证书链
       if(chain == null)
       {
              out.println("没有客户端证书链");
              return;
       }
       X509Certificate userCert= chain[0];     //客户证书
       ……
}
%>

.net c#
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Security.Cryptography.X509Certificates"%>
 
<%
if(Request.IsSecureConnection)
{
    HttpClientCertificate hCert = Request.ClientCertificate;
    if (hCert == null)
    {
           Response.Write("没有客户端证书");
           return;
    }
    X509Certificate2 cert = new X509Certificate2();
    try
    {
           cert.Import(hCert.Certificate);
    }
    catch (Exception e)
    {
           Response.Write(e.Message);
           return;
    }
    ......
}
%>
3.2表单方式
表单方式的原理是:服务器产生一个随机数;客户端用数字证书对应的私钥随机数签名,把随机数、用户证书、数字签名以PKCS#7格式打包发送到服务器;服务器再分析此PKCS#7数据包,得到签名随机数、用户证书和数字签名,再验证这3个元素是否有效。
3.2.1客户端
调用CAPICOM的JS脚本(capicom.js)
var CAPICOM_CURRENT_USER_STORE = 2;
var CAPICOM_STORE_OPEN_READ_ONLY = 0;
var CAPICOM_ENCODE_BASE64 = 0;
var CAPICOM_ENCODE_BINARY = 1;
 
var CAPICOM_INFO_SUBJECT_SIMPLE_NAME = 0;
var CAPICOM_INFO_ISSUER_SIMPLE_NAME = 1;
var CAPICOM_INFO_SUBJECT_EMAIL_NAME = 2;
var CAPICOM_INFO_ISSUER_EMAIL_NAME = 3;
 
function SelectMySignCert()
{
       //cert store
       var mystore = new ActiveXObject("CAPICOM.Store");
       mystore.Open(CAPICOM_CURRENT_USER_STORE,"My",CAPICOM_STORE_OPEN_READ_ONLY);
       var certs= mystore.Certificates;
       //myca sign certs
//     var mycacerts= certs;
       var mycacerts= new ActiveXObject("CAPICOM.Certificates");
       for(i=1;i<=certs.Count;i++)
       {
              //check issuer
              var issuer=certs.Item(i).IssuerName;
        if(issuer.indexOf("CN=MYCA")<0)     //not myca
                     continue;
              //check key usage
        var ku=certs.Item(i).KeyUsage();
        if(!ku.IsDigitalSignatureEnabled)   //not sign cert
                     continue;
              //add
              mycerts.Add(certs.Item(i));

       }
       if(mycerts.Count==0)
       {
              if(window.confirm("没有找到MYCA签发的证书,/r/n请插入相应的Ekey再按确定")==true)
                     return SelectMySignCert();
              else
                     return null;
       }
       //select cert
       var certsel= mycerts.Select("选择证书","请选择证书:",false);
       if(certsel==null)return null;
       var cert= certsel.Item(1);
//     cert.Display();
       return cert;
}
 
function SignText(strtext)
{
       //select cert
       var mysigncert= SelectMySignCert();
       if(mysigncert==null)return null;
       //signed data
       var signer = new ActiveXObject("CAPICOM.Signer");
       signer.Certificate = mysigncert;
       var signeddata = new ActiveXObject("CAPICOM.SignedData");
       var utils = new ActiveXObject("CAPICOM.Utilities");
       signeddata.Content = utils.BinaryStringToByteArray(strtext);
       return signeddata.Sign(signer,false,CAPICOM_ENCODE_BASE64);
}
/*
var signature= SignText("hello");
WScript.Echo(signature);
*/

登录页面(login.aspx)
<%@ Page Language="C#" %>
 
<%
       Random rnd = new Random();
       byte[] buff = new byte[18];
       rnd.NextBytes(buff);
       string challenge = Convert.ToBase64String(buff);
       Session["challenge"] = challenge;
%>
 
<html>
<head>
<title>登录页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<script src="./capicom.js"></script>
<script language="javascript">
function submitform()
{
       var signature= SignText("<%=challenge%>");
       if(signature==null)return;
       form1.passport.value= signature;
 
       form1.submit();
}
</script>

</head>
<body>
<object id="oCAPICOM"
       codeBase=" http://download.microsoft.com/download/E/1/8/E18ED994-8005-4377-A7D7-0A8E13025B94/capicom.cab #version=2,0,0,3"
       classid="clsid:A996E48C-D3DC-4244-89F7-AFA33EC60679">
</object>
<form name="form1" action="verify.aspx" method="POST">
       <input type="hidden" name="passport" value=""><br />
       <input type="button" value="点击提交登录证书." onclick="submitform()">
</form>
</body>
</html>
3.2.2服务端
JDK1.5中自带的JCE并不支持PKCS#7,.net framework是支持的。
登录判断逻辑(verify.aspx)
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Security.Cryptography.Pkcs"%>
<%@ Import Namespace="System.Security.Cryptography.X509Certificates"%>
 
<%
       string challenge = (string)Session["challenge"];
       Session["challenge"] = null;
       if(challenge==null){
              Response.Write("没有随机数");
              return;
       }
 
       string p = Request.Form["passport"];
       byte[] cmsDer = Convert.FromBase64String(p);
       SignedCms cms = new SignedCms();
       try{
              cms.Decode(cmsDer);
              cms.CheckSignature(true);
       }catch(Exception e){
              Response.Write(e.Message);
              return;
       }

       string challenge2 = Encoding.Default.GetString(cms.ContentInfo.Content);
       if (challenge.Equals(challenge2))
       {
              Response.Write("随机数不匹配<br/>");
//            Response.Write(challenge + ":" + challenge2);
              return;
       }
       Response.Write("登录成功");
       return;
 
%>

3数字证书与现有用户帐户的绑定

用户用数字证书登录后。WEB应用提供一个帐户绑定页面,页面提示用户输入原用户名和口令。后台再验证用户提交的用户名和口令,通过验证后,把该用户/口令对应的用户ID和用户的登录证书摘要写入到一个数据库表。流程:

以后用户使用该证书登录时,可以从数据库表查询到该证书对应的用户ID,系统给以该用户ID登录。

4一些有用的命令

关闭IIS的CRL检查:cscript c:/inetpub/adminscripts/adsutil.vbs set /w3svc/certcheckmode 1

KB977377补丁导致IIS的双向SSL认证失败

数字证书在web应用中实现登陆的更多相关文章

  1. RSA原理、ssl认证、Tomcat中配置数字证书以及网络传输数据中的密码学知识

      情形一:接口的加.解密与加.验签 rsa不是只有加密解密,除此外还有加签和验签.之前一直误以为加密就是加签,解密就是验签.这是错误的! 正确的理解是: 数据传输的机密性:公钥加密私钥解密是密送,保 ...

  2. JavaWeb学习篇之----Tomcat中配置数字证书以及网络传输数据中的密码学知识

    今天是学习JavaWeb的第二天,我们来了解什么呢?就了解一下Tomcat中配置数字证书的相关内容,但是在说这部分内容的时候,我们貌似得先说一下数字证书的相关概念,那说到数字证书的时候我们还得了解一些 ...

  3. 一文读懂Https的安全性原理、数字证书、单项认证、双项认证等

    本文引用了作者Smily(博客:blog.csdn.net/qq_20521573)的文章内容,感谢无私分享. 1.前言 目前苹果公司已经强制iOS应用必须使用HTTPS协议开发(详见<苹果即将 ...

  4. C#编程总结(十一)数字证书

    C#编程总结(十一)数字证书 之前已经通过文章介绍了数字证书的基础知识,包括加密和数字签名. 具体可见: 1.C#编程总结(七)数据加密——附源码 2.C#编程总结(八)数字签名 这里来讲述数字证书的 ...

  5. Https与Http,SSL,DevOps, 静态代码分析工具,RFID, SSH, 非对称加密算法(使用最广泛的一种是RSA), 数字签名, 数字证书

    在URL前加https://前缀表明是用SSL加密的. 你的电脑与服务器之间收发的信息传输将更加安全. Web服务器启用SSL需要获得一个服务器证书并将该证书与要使用SSL的服务器绑定. http和h ...

  6. 转: https 单向双向认证说明_数字证书, 数字签名, SSL(TLS) , SASL

    转自: http://www.cnblogs.com/mailingfeng/archive/2012/07/18/2597392.html 因为项目中要用到TLS + SASL 来做安全认证层. 所 ...

  7. 【转】Android数字证书

    Android数字证书的作用是非常重要的.Android操作系统每一个应用程序的安装都需要经过这一数字证书的签名. Android手机操作系统作为一款比较流行的开源系统在手机领域占据着举足轻重的地位. ...

  8. 数字证书, 数字签名, SSL(TLS) , SASL .

    因为项目中要用到TLS + SASL 来做安全认证层. 所以看了一些网上的资料, 这里做一个总结. 1. 首先推荐几个文章: 数字证书: http://www.cnblogs.com/hyddd/ar ...

  9. java-信息安全(四)-数据签名、数字证书

    概述 信息安全基本概念: 数字签名 数字证书 数字签名 数字签名(又称公钥数字签名.电子签章)是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法.一套数字签名 ...

随机推荐

  1. codeforces781D Axel and Marston in Bitland

    题目链接:codeforces781D 正解:$bitset$+状压$DP$ 解题报告: 考虑用$f[t][0.1][i][j]$表示从$i$出发走了$2^t$步之后走到了$j$,且第一步是走的$0$ ...

  2. Dive into Spring framework -- 了解基本原理(二)--设计模式-part2

    Template模式 Template模式顾名思义是提供了一种模板,也就是针对某种业务提供了模范框架.这个在spring中是属于核心模式的,因为其ApplicationContext抽象类就是模板模式 ...

  3. Java循环语句之 while

    生活中,有些时候为了完成任务,需要重复的进行某些动作.如参加 10000 米长跑,需要绕 400 米的赛道反复的跑 25 圈.在 Java 中实现功能时,也经常需要重复执行某些代码,例如,我们为了表示 ...

  4. Linux命令详解-rmdir

    rmdir是常用的命令,该命令的功能是删除空目录,一个目录被删除之前必须是空的.(注意,rm - r dir命令可代替rmdir,但是有很大危险性.)删除某目录时也必须具有对父目录的写权限. 1.命令 ...

  5. App压力测试MonkeyRunner整理

    压力测试结果:CRASH:崩溃,应用程序在使用过程中,非正常退出ANR:Application Not Responding 命令很多,不用死记,用到复制.粘贴就行,达到目的最重要. 简单通俗易懂点讲 ...

  6. for each/in/of的解释and example

    for-of 循环:代码示例for (var value of myArray) {console.log(value);}循环的对象需为一个数组 无法记录索引 可以相应break.continue. ...

  7. 8.初识Lock与AbstractQueuedSynchronizer(AQS)

    1. concurrent包的结构层次 在针对并发编程中,Doug Lea大师为我们提供了大量实用,高性能的工具类,针对这些代码进行研究会让我们对并发编程的掌握更加透彻也会大大提升我们队并发编程技术的 ...

  8. HDU-2196-树形dp/计算树上固定起点的最长路

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  9. 原生javascript-日历插件编写

    在线实例:http://lgy.1zwq.com/calendar/ 按照我们常用的日历格式,是7*6的格子,所以生成格子的总数就确定为42 例子:(如:2013年8月,这个时间为例子) /*---- ...

  10. 你真的会使用Chrome开发者工具吗?

    Chrome开发工具是一个Web开发者的利器,使用它你可以实现: 管理界面元素 断点调试JavaScript代码 优化你的代码 这里将列出一些非常实用的使用技巧,帮助你更加高效的工作 1. 快速编辑H ...