现在的位置: 首页 > 综合 > 正文

网站安全笔记

2013年12月09日 ⁄ 综合 ⁄ 共 29128字 ⁄ 字号 评论关闭

任务:

了解

1.了解网站安全的基础知识

2.基于代码级的JAAS认证和授权

 

理解

1.Web开发中的安全编码

2.数据加密

3.基于角色的认证和授权

 

运用

1.防止SQL注入

2.使用Java实现数据加密

--------------------------------------------------------------------------------------------------------

安全的基础知识

         网站安全的重要性

                   网站安全的应用场合

                            电子商务网站[淘宝、诈骗]

            电子政务网站[机密、形象]

            票务系统网站

                            公司内部系统[OA系统、越权访问]

        常见网站安全问题

                            拒绝服务(Dos Denial fo service)

                现象:大规模无效访问,造成网络阻塞,用户无法连接

                            非法登录

                                     获得网站用户的密码,在网站上为所欲为

                            数据库级别入侵

                                     任意改变数据库数据

                                     出售数据库数据

                            获得网站管理员权限,权限突破

                                     网站管理混乱

                                     无基本保护

         基本的安全属性

                   机密性(保密性)

            机密性就是保护数据避免被未授权用户访问的方法,简单地说只有合法的用户才能理解和接收正确的消息

                   完整性

                            确保合法用户最终获取的信息完整,未经篡改

                   可用性

                   可靠性

                            提供的服务不随时间地点的影响能够正常使用

                   不可否认性

         网站入侵的攻击方法和原理

                   暴力破解

                            对登录的口令密码进行破解

                            利用工具反复性的试探攻击

                            缩小海量级试探次数的方法

                                     字典档

                                     规则破解[生日组合扩展]

            常用攻击方法

                                     远程通讯法

                                               1.确定攻击目标(web/pop/telnet?)

                                               2.建立多进程的Socket通信

                                               3.通过字典当或规则生成密码

                                               4.发送密码试探

                                     本地文件破解

                                               1.截取机密后的密码

                                               2.通过字典或规则生成密码明文

                                               3.将密码铭文按加密算法加密

                                               4.将生成的密文和截取密文比较

                   sql注入

                            攻击原理

                                     在Web表单或查询字符串中输入特殊的sql命令

                                     实现欺骗服务器或绕过登录验证

                                               例如登录:

                                                        密码:'aa' or 1=1 --

                        select * from userswhere uname='zhangsan' and upass='aa' or 1=1 --'

        上传漏洞

                            攻击原理

                                     利用上传漏洞直接得到webshell

                网站服务器的安全漏洞

                                               原因:

                        .字符串过滤不严格

                                                        .文件类型没有检测

                                                        .上传未加权取[未进行权限验证]

        XSS跨站点攻击【XSS-Cross Site Scripting】

                            攻击原理

                                     恶意用户在网页中插入HTML或JS脚本

                                     引诱用户点击或输入用户隐私数据

                                     黑客获取用户账号、Cookie等隐私数据

                                     常见攻击方式:

                                               js方式

                                                        <ahref="http://知名站点url?变量名=    <script>document.location='http://localhost:8080/XSS_Attack/hack.jsp';alert(document.cookie);</script>">

                            钓鱼邮件图片或网站引诱图片等

                                                        </a>

                    iframe方式

                                                        <form id="shit"action="..." method="post"target="myframe"/>...

                        </form>

                        <iframe style="display:none"name="myframe"></iframe>

                    ajax方式

                                                        <script language="jscript">

                            v = newActiveXObject("MSXML2.XMLHTTP.3.0");

                            v.open("GET","url...");

                            v.send();

                            alert(v.statusText);

                    通过以上三种方式衍生出常用的攻击方式:

                                                        1.钓鱼邮件【邮件内容是知名网站的邀请等】

                                                        2.引诱图片链接

                                                       

                                                        </script>

        Cookie诈骗

                            原理:

                            Cookie是存放在客户端的用户数据

                            黑客可以通过修改本地Cookie来冒充管理员或用户

                   Dos攻击(拒绝服务攻击)

                   目前更流行DDos - 分布式拒绝服务攻击

                            攻击原理和过程:

                                     1.黑客寻找攻击目标

                                     2.黑客想傀儡控制机发出命令

                                     3.傀儡控制机向傀儡攻击机发出命令

                                     4.傀儡攻击机并发向目标发给攻击,引起正常访问失败。

                                               解决方案(网络管理员关心范畴):

                                                        加装报警器

                                                        加装防火墙

                                                        加强路由设置

         Web安全的防御思路

                   增加防御物

                            1.防火墙、VPN、内外网物理隔离

                            2.加密(传输内容)

            3.确认身份--[认证]

            4.控制访问资源--[授权]

            5.跟踪操作--审计和日志

         开发人员在进行Web开发是如何处理安全问题

                   概述:

                            严格验证用户输入数据:SQL注入、XSS安全漏洞

                   Web编程安全方面的经验法则主要有:

                            输入验证

                                     验证内容

                                               经典的安全法则:永远不要相信用户提交的数据,用户提交的数据永远都需要验证的

                                                        用户名、密码等格式

                                                        验证长度防止数据库溢出错误

                                                        邮件、手机、邮编等格式

                                     验证输入的方法

                                               客户端

                                                        写js脚本验证,过滤用户输入

                                               服务器端:

                                                        检测用户输入的合法性

                                                        强制转换用户输入

                                                        数据入库约束验证

 

                            防止SQL注入的解决思路

                                     客户端:

                                               .过滤或转义危险字符

                                               .使用正则表达式限制输入

                                     服务器端:

                                               .控制数据库的访问权限

                                               .分步验证用户名和密码

                                               .对账号做加密处理

                                     实践

                                     SQL注入示范:

                                               客户端使用正则表达式验证:

                                               <script>

                        function stripscript(s){

                            var pattern = newRegExp("!@#$%^&*()'?/-+=\\[\\].<>~%");

                            var rs ="";

                            for(vari=0;i<s.length;i++){

                                rs =rs+s.substr(i,1).replace(pattern,"");

                            }

                            return rs;

                        }

                        functioncheckAllTextValid(form){

                            //记录不含引号的文本框数量

                                                                 var resultTag = 0;

                            //记录所有text文本框数量

                                                                 var flag=0;

                            for(vari=0;i<form.elements.length;i++){

                                if(form.elemengts[i].type=="text"){

                                    flag = ++;

                                    if(/^['\-"'<>]*$/).test(form.elements[i].value)

                                        resultTag++;

                                    else

                                        form.elements[i].select();

                                }

                            }

                            if(resultTag==flag)

                                return true;

                            else{

                                alert("文本框中不能包含:\n\n1 单引号\n 2 双引号 \3 竖线\n\n请重新检查输入内容");

                                return false;

                            }

                   

                        }

                    </script>

                    服务器端使用正则表达式验证:

                                                        public class SpecialTokenFilter{

                            public static StringstringFilter(String str){

                                //清除掉所有特殊字符

                                                                           String regEx ="[!@#$%^&*()'?/-+=\\[\\].<>~%]";

                                Pattern p =Pattern.compile(regEx);

                                Matcher m =p.matcher(str);

                                returnm.replaceAll("").trim();

                            }

                        }              

 

            图片验证码

                                     目的:避免暴利攻击

                                     验证码的原理:

                                               1.随机生成验证码图片

                                               2.发送图片,同时存入Session

                    3.提交输入的验证码及表单数据

                                               4.读取Session,和用户的输入逇验证码比较

                                               5.根据比较结果确定是否执行DB操作

                            防范跨站脚本XSS攻击

                                     解决思路:

                                               实行严格的输入验证

                                               实现Session标记等

                                               进行HTML的格式化

                                     示范:

                                              

数据加密

         概述:

                   Java中默认情况是关闭了沙箱功能的,如果运行中开启了沙箱后又没有进行任何授权,那么程序进行一个操作的时候会报错,因为当前操作没有被授权,Java安全体系结构中最基本的思路:所有的操作都要经过认证和授权才能进行操作

         Java提供的安全模型和API

        Java语言本身的安全性

                            自动内存管理

                            自动数组溢出检查等

                            字节代码的验证机制

                            独特的安全类加载

                   Java加密体系

                            JCA和JCE是两个重要的框架

                            JCA:Java Crytography Architecture[Java加密的基本框架]

                数字签名

                                     信息摘要

                            JCE:Java Crytography Extension[Java加密扩展框架]

                MD5(消息摘要算法)

                SHA(安全散列算法)

                DES(数据加密算法)

                自从JDK1.4之后JCE和JDK已经捆绑发行了

                            这两个框架都遵守“算法和实现的独立”特点,它们都通过额外的框架提供服务,使用时不需要关心具体的加密细节,Java平台已经帮助您实现了加密算法,您只管调用相应类就可以了

                   Java的认证和授权

                            Java平台在认证和授权方面有一套独立的框架JAS,对于开发中间件来说用JAS比较多,什么是中间件呢?简单地说就是给开发商开发人员用的软件,比如tomcat、jboss、weblogic,他们是比较通用的东西,不面向具体客户,对于具体客户(终端用户),比如银行、电信,JAS使用就比较少,在面向终端用户进行开发的时候,对于安全方面一般都会采用配置文件方式进行认证和授权。

                            基于配置文件的认证和授权

                                     特点:

                                               只需配置配置文件,方便修改

                                               应用场合:一般适用于B/S开发

                                               安全控制粒度:一般只能到某个页面(不能控制到代码方法,但是大多数网站只需控制到Web层就可以了)

                    如果想将控制粒度提高到代码级别,那么就需要基于源代码的认证和授权

                            基于源代码的认证和授权

                                     特点:

                                               安全控制粒度:可以控制到某个类甚至方法

                                               应用场合:C/S或B/S开发均可

                                               JAAS: Java Authentication and AuthorizationService

                    解决了传统的访问控制安全问题(传统的访问控制只能看代码从哪里来,谁签的名,很容易代码黑客攻击,还应该判断谁在执行代码,JAAS解决了这个问题)

                    JAAS通过可插拔方式在应用中嵌入安全的认证和授权模块,安全控制起来很方便,另外客户端不管是一个应用还是一个application还是一个Bean还是一个Servlet

        安全通信

                                     概述:

                                               当信用卡用户密码私有信息通过网络传输时,这些信息可能被他人窃取,我们需要确保这些通讯的安全,Java提供了对标准安全通信协议的实现API

                Java提供了对标准安全通信协议的实现API

                    SSL Secure Socket Layer(安全套接层协议)

                    TLS Transport LayerSecurity(安全传入层协议),这是SSL的升级版本

                                               Kerberos(一种网络认证协议)

                当然这些协议的实现是以牺牲性能为代价的。

                   PKI体系

                                     Public Key Infrastructure,主要用于“基于公钥体系”的信息安全交换

                                     Java的PKI规范提供了管理Key和证书的API

                    实现协议

                                                        X.509(最常用)

                        CRL(证书撤销列表)

                        PKCS等

                                               PKI的核心是数字证书

                                                        提供Certifficate数字证书对象等

                                               管理证书的工具

                                                        keytool

                        jarSignner

    加密基础知识

                   加密算法分为两类:

                   对称加密(私钥体系)

            特点:

                                     单钥,用同一把钥匙加密和解密

                                     加密/解密速度快,安全性取决于私钥的保管

                                     是一种可逆算法

                            典型算法:

                                     DES(数据加密算法,58位,安全性不够高)

                AES(高级加密标准,128位,常用)

        非对称加密(公钥体系)

            特点:

                                     加密用公钥,解密用私钥

                                     安全性较高,加密/解密慢,适用于分布式网络

                                     典型应用:数字证书

                            典型算法:

                                     RSA算法

                                     DSA算法

                   单向散列函数

                            h = H(m)返回长度为m的散列值h,H是算法,生成的h值不可逆

                                     例如:

                                               goodday ==> (MD%单向散列函数h=H(m))==> 0CF21CE35322D2E56D745E319B933470

            使用单向散列函数对明文进行加密是目前各大网站使用最多的算法,因为生成的密码文不可逆。

                            特点:

                                     加密快、不可逆、破解困难

                            典型算法:

                                     MD5(128位,安全性不够高,目前已被中国人通过碰撞法破解)    

                SHA或SHA1(160)

        非对称加密和单向散列函数加密有什么区别呢?

                            非对称加密用的是公钥加密私钥解密,但是单向散列函数只对既定信息用固定算法加密,但是不存在解密这么一个过程,是一个不可逆加密过程

 

         使用Java实现加密

                   示范,使用MD5实现加密[散列加密,生成密码不可逆]:

                            /*

            *散列加密MD5算法

                            *MD5生成的密码不可逆

                            *使用MD5步骤:

                            *   1.生成MD5算法的对象

                            *   2.使用MD5算法加密明文

                            *   3.获取MD5摘要,返回一个字节数组(散列值)

            *   4.将字节数组生成为加密后的密码字符串

                            *   MD5目前还是很对企业对于密码保护的主要措施

                            */

            public class MD5{

                public void gernerateMD5(stringtext) throws NoSuchAlgorithmExcpetion{

                    //第一步

                                               MessageDigestmd5 = MessageDigest.getInstance("MD5");

                    //第二步

                                               md5.update(text.getBytes());

                    //第三步

                                               byte[]hashcode = md5.digest();

                    //第四步

                                               StringBuffer md5_str = newStringBuffer(hashcode.length<<1);

                    for(inti=0;i<hashcode.length;i++){

                        md5_str.append(Character.forDigit((hashcode[i]>>4)&0xf,16));

                    }

                    System.out.println(md5_str.toString());

                }

                            }

 

                   示范,使用对称加密给文本加密

                            import java.io.IOException;

import java.io.InputStreamReader;

import java.io.UnsupportedEncodingException;

import java.security.*;

import java.util.Scanner;

import javax.crypto.*;

import javax.crypto.spec.SecretKeySpec;

 

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

 

 

class SymmetricEncoder{

       /*

       *加密过程

       *1.构造密钥生成器

       *2.根据encodeRules初始化密钥生成器

       *3.产生密钥

       *4.创建和初始化密码器

       *5.内容加密

       *6.返回字符串

       */

       public static String AESEncode(StringencodeRules,String content){

              try {

                     //1.构造密钥生成器,指定AES算法

                     KeyGeneratorkeygen= KeyGenerator.getInstance("AES");

                     //2.初始化密钥生成器

                     keygen.init(128,newSecureRandom(encodeRules.getBytes()));

                     //3.产生原始对称密钥

                     SecretKeyoriginal_key = keygen.generateKey();

                     //4.获得原始对称密钥字节数组

                     byte[] raw =original_key.getEncoded();

                     //5.生成密钥

                     SecretKeySpeckey = new SecretKeySpec(raw,"AES");

                     //6.根据指定算法AES创建密码器

                     Ciphercipher = Cipher.getInstance("AES");

                     //7.初始化密码器

                     cipher.init(Cipher.ENCRYPT_MODE,key);

                     //8.获取加密内容字节数组

                     byte[] byte_encode =content.getBytes();

                     //9.根据密码器初始化的方式加密:将数据加密

                     byte[] byte_AES =cipher.doFinal(byte_encode);      

                     //10.将加密后的数据转换为字符串

                     StringAES_encode = new String(newBASE64Encoder().encode(byte_AES));

                     return AES_encode;

              } catch (InvalidKeyException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (NoSuchAlgorithmException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (NoSuchPaddingException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (IllegalBlockSizeException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (BadPaddingException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

              return "";

       }

       /*

       *解密过程

       *1.构造密钥生成器

       *2.根据encodeRules初始化密钥生成器

       *3.产生密钥

       *4.创建和初始化密码器

       *5.将加密后的字符串反编码成byte[]数组

       *6.将加密内容解密

       */

       public static String AESDEncode(StringencodeRules,String content){

              try {

                     //1.构造密钥生成器,指定AES算法

                     KeyGeneratorkeygen= KeyGenerator.getInstance("AES");

                     //2.初始化密钥生成器

                     keygen.init(128,newSecureRandom(encodeRules.getBytes()));

                     //3.产生原始对称密钥

                     SecretKeyoriginal_key = keygen.generateKey();

                     //4.获得原始对称密钥字节数组

                     byte[] raw =original_key.getEncoded();

                     //5.生成密钥

                     SecretKeySpeckey = new SecretKeySpec(raw,"AES");

                     //6.根据指定算法AES创建密码器

                     Ciphercipher = Cipher.getInstance("AES");

                     //7.初始化密码器

                     cipher.init(Cipher.DECRYPT_MODE,key);

                     //8.将加密并编码后的内容解码成字节数组

                     byte[] byte_content = newBASE64Decoder().decodeBuffer(content);

                     //9.解密content

                     byte[] byte_decode =cipher.doFinal(byte_content);

                     StringAES_encode = new String(byte_decode,"utf8");

                     return AES_encode;

              } catch (InvalidKeyException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (NoSuchAlgorithmException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (NoSuchPaddingException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (IllegalBlockSizeException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (BadPaddingException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (UnsupportedEncodingException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              } catch (IOException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

              return "";

       }

}

 

public static void main(String[] args) {

              Stringdecode = SymmetricEncoder.AESEncode("jiang","accp");

              System.out.println("accp加密后:"+decode);

              System.out.println(decode+"解密后:"+SymmetricEncoder.AESDEncode("jiang",decode));

       }

基于页面级的认证和授权

           Servlet规范规定的认证方式

                 Servlet规范中基于角色控制的实现思路:

                       域(realm) 用户的集合[类似于用户组的概念]

               用户(user)

               密码(password)

               所属角色(role)

            对于遵守Servlet规范的服务器来说,比如tomcat,它就包含了一个域,这个域在conf/tomcat-users.xml中进行配置的,如下:

<tomcat-users>

  <rolerolename="tomcat"/>

  <rolerolename="role1"/>

  <userusername="tomcat" password="tomcat"roles="tomcat"/>

  <userusername="both" password="tomcat"roles="tomcat,role1"/>

  <userusername="role1" password="tomcat"roles="role1"/>

</tomcat-users>

 

它配置了用户名密码、角色这些信息,但不包含权限信息。某个页面或文件要被哪些角色角色权访问的权限信息要在web.xml文件中进行配置,如下图:


用户、角色:

tomcat-users.xml

访问权

Web.xml

           Servlet规范的四种认证方式:

                 Basic验证

概述:

浏览器弹出登录窗体要求输入用户名和密码信息

                       特点:

                              明文传送口令,安全性低。

            Digest验证

                            概述:采用消息摘要加密的方式传送口令,安全性较高

                            特点:消息摘要方式传送、安全性较高。常见的MD5或者SHA加密都属于这类

                            实现步骤:

1、   配置tomcat-users.xml文件(也可配置在各应用下)

a)    指定用于的角色名、用户、用户密码、所属角色,例如:

i.     <role rolename=”角色名”/>

ii.     <user username=”用户名” password=”加密后的密码” roles=”所属角色名”/>

b)    然后密码使用digest命令加密

2、   之后配置Server.xml,设为Digest验证方式

a)    <realm className=”…..” digest=”md5”/>

3、   然后再配置具体应用的Web.xml

代码示范:

1.    在WebRoot下创建一目录protected,将受保护的jsp文件放入

2.    配置当前项目的web.xml

<security-constraint>

       <web-resource-collection>

            <url-pattern>/protected/*</url-pattern>

       </web-resource-collection>

       <auth-constraint>

            <role-name>admin</role-name>

       </auth-constraint>

</security-constraint>

<login-config>

       <auth-method>DIGEST</auth-method>

</login-config>

<security-role>

       <role-name>admin</role-name>

</security-role>

            3.在tomcat的tomcat-users.xml文件里面添加自己的角色admin和用户manager

<tomcat-users>

  <rolerolename="tomcat"/>

  <rolerolename="role1"/>

  <rolerolename="admin"/>

  <userusername="manager" password="manager"roles="admin"/>

  <userusername="tomcat" password="tomcat"roles="tomcat"/>

  <userusername="both" password="tomcat"roles="tomcat,role1"/>

  <userusername="role1" password="tomcat"roles="role1"/>

</tomcat-users>

 

Tomcat是如何找到tomcat-user.xml并进行验证的呢?

                                   当使用Digest认证的时候,Tomcat会找Server.xml下面的这个域<RealmclassName="org.apache.catalina.realm.UserDatabaseRealm"

            resourceName="UserDatabase"/>,“org.apache.catalina.realm.UserDatabaseRealm”这个类就会去查找tomcat-users.xml

            Form验证

                            概述:常见的表单验证,和Basic验证一样采用明文方式传送口令,安全性低。

                            特点:安全性低,但可以自定义页面。

                实现步骤:

1.配置当前项目的web.xml

<security-constraint>

       <web-resource-collection>

              <url-pattern>/protected/*</url-pattern>

       </web-resource-collection>

       <auth-constraint>

              <role-name>admin</role-name>

       </auth-constraint>

</security-constraint>

<login-config>

       <auth-method>FORM</auth-method>

       <form-login-config>

       <form-login-page>/security_lgoin.jsp</form-login-page>

       <form- error -page>/error.jsp</form-error-page>

       </fogm-login-config>

</login-config>

<security-role>

       <role-name>admin</role-name>

</security-role>

2.创建security_lgoin.jsp页面

<form action="j_security_check"method="post">

           <p>账户:<input type="text" name="j_username"/></p>

           <p>密码:<input type="password" name="j_password"/></p>

           <p><input type="submit" value="login"/></p>

</form>

      3.在目录protected下创建保护页面archivelist.jsp

                  <body>

                     <h3>正确访问档案信息</h3>

         </body>

      4.创建错误页面

      5.在tomcat-users.xml文件中配置角色和用户

<tomcat-users>

  <role rolename="tomcat"/>

  <rolerolename="admin"/>

  <role rolename="role1"/>

  <user username="both"password="tomcat" roles="tomcat,role1"/>

  <user username="tomcat"password="tomcat" roles="tomcat"/>

  <userusername="jiang" password="jiang"roles="admin"/>

  <user username="role1"password="tomcat" roles="role1"/>

</tomcat-users>

  红颜色是添加的角色和用户

  6、部署并启动项目

  7、浏览器地址栏输入要访问的保护页面地址,自动出现登录页面正确即进入保护页面,用户名密码不正确进入错误页面,用户名密码正确但未通过授权则显示:

HTTP Status 403 - Access to the requestedresource has been denied

       注意正确的用户名和密码是jiang/jiang,tomcat/tomcat也是可以通过认证的用户名和密码但是不能通过授权,会出现403错误

           如何将用户角色信息放入数据库

1.   创建用户表和角色表

a)     用户表(userName、password)

b)      角色表(userName、roleName)

2. 更改Context.xml文件,设置数据库驱动等信息

   <Context>

       <RealmclassName="org.apache.catalina.realm.JDBCRealm"

          driverName="驱动程序名称" connectionURL="URL"

          userTable="用户表名" userNameCol="用户字段名"

          userCredCol="密码字段名" userRoleTable="角色表名"

          roleNameCol="角色字段名" />

   </Context>

   注意:将驱动程序的jar文件放入到tomcat的common的lib下

2.   到数据库创建相应的表

3.   修改Server.xml文件

<RealmclassName="org.apache.catalina.realm.UserDatabaseRealm"

             resourceName="UserDatabase"/>

 

     <!-- Comment out the old realm but leave here for now in case we

          need to go back quickly -->

     <!--

      <RealmclassName="org.apache.catalina.realm.MemoryRealm" />

      -->

 

     <!-- Replace the above Realm with one ofthe following to get a Realm

           stored in a database and accessedvia JDBC -->

 

     <!--

      <Realm className="org.apache.catalina.realm.JDBCRealm"

             driverName="org.gjt.mm.mysql.Driver"

         connectionURL="jdbc:mysql://localhost/authority"

         connectionName="test"connectionPassword="test"

              userTable="users"userNameCol="user_name" userCredCol="user_pass"

          userRoleTable="user_roles"roleNameCol="role_name" />

     -->

 

      <!--

      <Realm className="org.apache.catalina.realm.JDBCRealm"

             driverName="oracle.jdbc.driver.OracleDriver"

         connectionURL="jdbc:oracle:thin:@ntserver:1521:ORCL"

         connectionName="scott"connectionPassword="tiger"

              userTable="users"userNameCol="user_name" userCredCol="user_pass"

          userRoleTable="user_roles"roleNameCol="role_name" />

     -->

    将蓝色的部分代码注释掉,然后根据您使用的数据库用一段红色的代码替换。绿色的部分就是告诉我们可以用下面的域去替换上面的域。

注意:将驱动程序的jar文件放入到tomcat的common的lib下

 

            Client-Cert验证

                            概述:采用数字证书验证方式加密,安全性较高。

                            特点:采用数字证书方式,一般和SSL配合(要开启SSL)

                       为什么需要数字证书?

                              数字证书就是在数字签名的基础上应运而生的。

                            数字签名的原理

                              数字签名:公钥+私钥的一种应用

                       常用的数字签名算法有RSA和DSA算法


流程:

       发送方对发送消息物理签名,接收方法验证签名,发送方利用软件生成公钥和密钥对,将公钥告知信任的人,私钥自己保管

1.发送方对发送内容产生一个消息摘要,该摘要是唯一的,只要发送内容被篡改,摘要将会变化。

2.           发送方对消息摘要使用私钥进行加密,连同发送内容一同发送给接收方。

3.           接收方接收到内容后利用发送者的公钥解开加密后的消息摘要值,如果发送方的公钥无法解开消息摘要值,那么说明这个消息不是发送方发送的消息,从而证实当前的信息来源是否真实。

4.           接收方法对接收内容重新产生消息摘要值,并比较这个摘要值是否和第3步中解密的消息摘要值相等,如果不相等,说明发送的消息被篡改过。如果相等说明没有被篡改过,是完整的信息。

数字证书的原理

       概述:数字签名的安全性已经较高了,但是涉及到网上交易,比如淘宝、支付宝。因为在交易时数字签名还不能确定对方的合法性,它需要第三方机构来证明。这个时候就要采用数字证书,它是通过第三方机构(比如银行)颁发的证书来证明你的身份,从而保证您的身份是唯一的。在网上交易时,商务交易双方都信任第三方,即CA(CertificateAuthority)证书颁发机构,这个第三方机构负责发放、管理、验证数字证书。它是电子商务中的关键环节。和身份证一样,首先由第三方证书发布机构向申请者发布证书,类似于由公安机关给申请者发放身份证一样。身份证是你的唯一标识,身份证除了你的基本信息外,还有公安机关的章。数字证书也有相应机构的章,数字证书的内容:申请者的信息、申请者的公钥、CA(CertificateAuthority)证书颁发机构的数字签名。

数字证书的原理:

1.数字证书是数字签名的运用。采用公钥+私钥加密方式,私钥自己保管,用于解密和签名。

2.公钥由用户供发给自己信任的人用于加密和验证签名。发布方用接收方的公钥加密,接收方用自己的私钥解密。和数字签名的道理一样。因为有第三方机构的参与,所以还能够证实对方的合法性

3.为了交易更加安全,从而保证数据的真实性、完整性、合法性外还需要对发送的所有内容进行加密传送,以避免数据被黑客窃取,所以数字证书需要结合SSL使用,数字证书是一个双向验证过程,而SSL是双向认证通道。所以数字证书一般都需要和SSL这个通道结合使用。

事例说明如下:

例如:比如有两个用户Alice和Bob,Alice想把一段明文通过双钥加密的技术发送给Bob,Bob有一对公钥和私钥,那么加密解密的过程如下:

  Bob将他的公开密钥传送给Alice.

  Alice用Bob的公开密钥加密她的消息,然后传送给Bob。

  Bob用他的私人密钥解密Alice的消息。

  那么Bob怎么可以辨认Alice是不是真人还是冒充的。我们只要和上面的例子方法相反就可以了。

  Alice用她的私人密钥对文件加密,从而对文件签名。

  Alice将签名的文件传送给Bob.

  Bob用Alice的公钥解密文件,从而验证签名。

    Java中数字证书的实现思路

       在jdk中可以实现数字证书的发布,步骤如下:

       1.使用keytool等工具生成服务器端密钥仓库

2.在tomcat中配置启用SSL

3.导出服务器端证书

4.生成客户端密钥仓库

5.在客户端导入服务器端证书

示范:

为服务器生成证书

     为客户端生成证书

     导出cer文件

让服务器可以信任客户端证书

       查看服务器证书信息(看是否成功导入客户端证书信息)

    keytool-list -keystore tomcat.keystore

   

       配置tomcat

           步骤一:打开服务器Server.xml文件

           步骤二:开启SSL通道

           开启以下节点并进行配置:

   

           步骤三:将证书导入到浏览器中

           双击证书client.p12:

接下来启动tomcat

打开浏览器输入:https://localhost:8443,如过出现安全警告选择继续浏览网站即可。

 

基于代码级的认证和授权JAAS(Java AuthenticationAnd Authorization Service)

    JAAS的特点

       JAAS是对JCE安全框架的重要补充

       提供基于用户认证和授权的动态安全解决方案

       可插拔(Pluggable)的方式,Java程序和底层认证分开。只需通过配置既可以了。

      

 

    JAAS的架构,如下图:


    说明:

       .应用程序只需要和LoginContext登录上下文进行交互

       .在LoginContext下是一组可配置的LoginModules对象,这些对象是通过配置文件进行配置的。

       .针对LoginModules提供了各种实现类,如LDAP\RDBMS….

    JAAS认证:

       JAAS提供了先认证后授权思路的相应的API。

       认证方面的常用类和接口:

           LoginModule:登录模块(确认用户的合法性,确认用户名密码的合法性)

           LoginContext:登录上下文(应用程序只和这个模块打交道,为了实现用户鉴别鉴定相应的环境,从配置文件从读取出安全验证需要哪些LoginModule)

           CallbackHandler:回调处理器(验证的时候和用户的交互采用该接口完成,比如需要的用户名密码、验证结果等)

           Subject:验证实体/主体(就是表示当前要验证的东西,有可能是一个用户、有可能是一个WebService、有可能是一个Bean)

           Principal:身份/标识(表示具有某种访问权限的一个实体,可以看做是要执行某种操作所需要的一个身份证件,Subject能执行什么操作是什么身份就由Principal这个类来体现)

           下面用一个图示来理解以上类和接口的关系:

      

    描述:

1.   军事院校校方LoginModule要根据学生(Subject)的入学通知来确定其合法性

2.   校方将具体工作交由门卫兵(CallbackHandler)来执行

3.   门卫和学生交流要求出示入学通知书

4.   门卫将入学通知的确认结果告知校方领导,并作出相应处理。

5.   校方根据学生身份发给相应的身份证件(比如士官身份证件或者将军身份证件)

6.   学生(Subject)根据自己的身份证件(Principal)的级别可以访问学校的不同的资源。如果是士官级别只能访问士官级别的资源,如果是将军级别只能访问将军级别资源。

7.   当然一个学生可以有多个军衔(既是将军又是校长)

JAAS认证原理

        设置JAAS配置文件

初始化loginContext对象,根据配置文件加载一个或多个LoginModule

通过调用LoginContext的login方法,最终将调用每个LoginModule的login方法来验证

JAAS认证的Java实现

n       编写主程序验证代码(客户端代码)

n       自定义登录模块(实现LoginModule接口)

l       主要实现以下5个方法:

n       abort();

n       commit();

n       initialize();

n       login();

n       loginout();

n       创建用户信息管理类(实现CallbackHandler接口)

n       实现身份标识类(实现Principal接口)

n       配置认证策略文件(*.config)

 

示范

    自定义登录模块(实现LoginModule接口)下login()方法的实现:

创建用户信息管理类(实现CallbackHandler接口):

   handle(Callbacck[]callbacks)

常见的callback类别

NameCallback

PasswordCallback

    实现身份标识类(实现Principal接口)

       Equal()

       getName()

       hashCode()

       toString()

    配置认证策略文件(*.config)

       Required(必须)

       Optional(可选)

       Requisite(必须)

       Sufficient(充分)

4.执行时指定配置文件

a)     Java –Djava.security.auth.login.config=login.conf

 

JAAS授权的实现

       用户已经通过认证(已经确认你是谁)

       配置基于Principal的授权策略文件

       用Subject的doAs/doAsPrivileged(执行敏感资源的访问)

抱歉!评论已关闭.