网站安全笔记

任务:

了解

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(执行敏感资源的访问)

JAAS授权的Java实现

实现授权的主程序代码

//…身份验证【调用login()方法后,被验证实体subject将填充表示能访问敏感资源的一个或多个Principal】

loginContext.login();

//…通过身份认证后

Subject mysubject=loginContext.getSubject();//获得通过验证后的subject

PrivilegedAction action = newCheckAccountAction();//创建访问敏感资源的特权动作action在run方法中具体实现

Subject.doAdPrivileged(mysubject,action,null);// 以subject的身份来执行特权动作(访问敏感资源)

实现敏感资源访问类(实现PrivilegedAction接口)

public classCheckAccountAction implements PrivilegedAction{

//@Override

public Object run() {

// TODOAuto-generated method stub

AccessController.checkPermission(newSimplePermission("operate"));

System.out.println("允许用户操作账户");

return new Integer(0);

}

}

配置授权策略文件jaas.policy

语法:

grant <signer(s)签名者>,<codeBase代码源url>

<Principal表示类>{

permission权限类名"target_name","action";

permission权限类名"target_name","action"

};

根据具体操作选择Permisson实现类:

网站安全笔记

以指定的身份执行特权动作来访问敏感资源

Subject.doAs(subject,action)

Subject.doAdPrivileged(subject,action,指定的访问控制上下文对象)

原文链接:https://blog.csdn.net/jiangtongcn/article/details/7270325

原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/18120

(0)
上一篇 2023年6月20日
下一篇 2023年6月20日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

优速盾注册领取大礼包www.cdnb.net
/sitemap.xml