`

java security / SSL / TLS / md5 / sha / base64 / rsa / des / aes / 3des

    博客分类:
  • Java
阅读更多

 

 

java jdk keytool

C:\Program Files\Java\jdk1.7.0_11\bin\keytool.exe

[lindows@Loadrunner19 ~]$ ll /opt/soft/jdk1.7.0_11/bin/keytool 
-rwxrwxrwx 1 lindows lindows 7957 Jan 12 18:05 /opt/soft/jdk1.7.0_11/bin/keytool

 

tomcat7 开启https ,使用JDK 7的keytool 生成tomcat证书

http://lixor.iteye.com/blog/1532655

https单向/双向认证的tomcat配置攻略

http://xiaohuafyle.iteye.com/blog/1538719

C:\Program Files\Java\jdk1.7.0_11\bin>keytool -v -genkey -alias tomcat -keyalg RSA -keystore d:/tomcat.keystore

 

C:\Program Files\Java\jdk1.7.0_11\bin>keytool.exe -help

Dos代码
  1. 密钥和证书管理工具  
  2. 命令:  
  3.  -certreq            生成证书请求  
  4.  -changealias        更改条目的别名  
  5.  -delete             删除条目  
  6.  -exportcert         导出证书  
  7.  -genkeypair         生成密钥对  
  8.  -genseckey          生成密钥  
  9.  -gencert            根据证书请求生成证书  
  10.  -importcert         导入证书或证书链  
  11.  -importkeystore     从其他密钥库导入一个或所有条目  
  12.  -keypasswd          更改条目的密钥口令  
  13.  -list               列出密钥库中的条目  
  14.  -printcert          打印证书内容  
  15.  -printcertreq       打印证书请求的内容  
  16.  -printcrl           打印 CRL 文件的内容  
  17.  -storepasswd        更改密钥库的存储口令  
  18. 使用 "keytool -command_name -help" 获取 command_name 的用法  

 
C:\Program Files\Java\jdk1.7.0_11\bin>keytool.exe -genkey -help

Dos代码
  1. keytool -genkeypair [OPTION]...  
  2. 生成密钥对  
  3. 选项:  
  4.  -alias <alias>                  要处理的条目的别名  
  5.  -keyalg <keyalg>                密钥算法名称  
  6.  -keysize <keysize>              密钥位大小  
  7.  -sigalg <sigalg>                签名算法名称  
  8.  -destalias <destalias>          目标别名  
  9.  -dname <dname>                  唯一判别名  
  10.  -startdate <startdate>          证书有效期开始日期/时间  
  11.  -ext <value>                    X.509 扩展  
  12.  -validity <valDays>             有效天数  
  13.  -keypass <arg>                  密钥口令  
  14.  -keystore <keystore>            密钥库名称  
  15.  -storepass <arg>                密钥库口令  
  16.  -storetype <storetype>          密钥库类型  
  17.  -providername <providername>    提供方名称  
  18.  -providerclass <providerclass>  提供方类名  
  19.  -providerarg <arg>              提供方参数  
  20.  -providerpath <pathlist>        提供方类路径  
  21.  -v                              详细输出  
  22.  -protected                      通过受保护的机制的口令  
  23. 使用 "keytool -help" 获取所有可用命令  

 
 linux jdk7 keytool

[lindows@Loadrunner19 ~]$ /opt/soft/jdk1.7.0_11/bin/keytool --help

Shell代码
  1. Key and Certificate Management Tool  
  2. Commands:  
  3.  -certreq            Generates a certificate request  
  4.  -changealias        Changes an entry's alias  
  5.  -delete             Deletes an entry  
  6.  -exportcert         Exports certificate  
  7.  -genkeypair         Generates a key pair  
  8.  -genseckey          Generates a secret key  
  9.  -gencert            Generates certificate from a certificate request  
  10.  -importcert         Imports a certificate or a certificate chain  
  11.  -importkeystore     Imports one or all entries from another keystore  
  12.  -keypasswd          Changes the key password of an entry  
  13.  -list               Lists entries in a keystore  
  14.  -printcert          Prints the content of a certificate  
  15.  -printcertreq       Prints the content of a certificate request  
  16.  -printcrl           Prints the content of a CRL file  
  17.  -storepasswd        Changes the store password of a keystore  
  18. Use "keytool -command_name -help" for usage of command_name  

 

 [root@Loadrunner19 bin]# /usr/bin/keytool -?

Shell代码
  1. Unrecognized command: --help  
  2. Usage:  keytool [COMMAND] [-- COMMAND]...  
  3. Manage private keys and public certificates.  
  4.   
  5. Available commands:  
  6.   -genkey         Generate a Key Entry, eventually creating a key store.  
  7.                     [-alias ALIAS] [-keyalg ALGORITHM] [-keysize KEY_SIZE]  
  8.                     [-sigalg ALGORITHM] [-dname NAME] [-keypass PASSWORD]  
  9.                     [-validity DAY_COUNT] [-storetype STORE_TYPE]  
  10.                     [-keystore URL] [-storepass PASSWORD]  
  11.                     [-provider PROVIDER_CLASS_NAME] [-v].  
  12.   -import         Add Key Entries and Trusted Certificates.  
  13.                     [-alias ALIAS] [-file FILE] [-keypass PASSWORD]  
  14.                     [-noprompt] [-trustcacerts] [-storetype STORE_TYPE]  
  15.                     [-keystore URL] [-storepass PASSWORD]  
  16.                     [-provider PROVIDER_CLASS_NAME] [-v].  
  17.   -selfcert       Generate a self-signed Trusted Certificate.  
  18.                     [-alias ALIAS] [-sigalg ALGORITHM] [-dname NAME]  
  19.                     [-validity DAY_COUNT] [-keypass PASSWORD]  
  20.                     [-storetype STORE_TYPE] [-keystore URL]  
  21.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].  
  22.   -identitydb     NOT IMPLEMENTED YET.  Import JDK1.1 Identity Database.  
  23.                     [-file FILE] [-storetype STORE_TYPE] [-keystore URL]  
  24.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].  
  25.   -certreq        Issue a Certificate Signing Request (CSR).  
  26.                     [-alias ALIAS] [-sigalg ALGORITHM] [-file FILE]  
  27.                     [-keypass PASSWORD] [-storetype STORE_TYPE] [-keystore URL]  
  28.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v]  
  29.                     [-attributes].  
  30.   -export         Export a Certificate from a key store.  
  31.                     [-alias ALIAS] [-file FILE] [-storetype STORE_TYPE]  
  32.                     [-keystore URL] [-storepass PASSWORD]  
  33.                     [-provider PROVIDER_CLASS_NAME] [-rfc] [-v].  
  34.   -list           Print one or all Certificates in a key store to STDOUT.  
  35.                     [-alias ALIAS] [-storetype STORE_TYPE] [-keystore URL]  
  36.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME]  
  37.                     [-rfc] [-v].  
  38.   -printcert      Print a human-readable form of a Certificate in a FILE.  
  39.                     [-file FILE] [-v].  
  40.   -keyclone       Clone a Key Entry in a key store.  
  41.                     [-alias ALIAS] [-dest ALIAS] [-keypass PASSWORD]  
  42.                     [-new PASSWORD] [-storetype STORE_TYPE] [-keystore URL]  
  43.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].  
  44.   -storepasswd    Change the password protecting a key store.  
  45.                     [-new PASSWORD] [-storetype STORE_TYPE] [-keystore URL]  
  46.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].  
  47.   -keypasswd      Change the password protecting a Key Entry in a key store.  
  48.                     [-alias ALIAS] [-keypass PASSWORD] [-new PASSWORD]  
  49.                     [-storetype STORE_TYPE] [-keystore URL]  
  50.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].  
  51.   -delete         Delete a Key Entry or a Trusted Certificate from a key store.  
  52.                     [-alias ALIAS] [-storetype STORE_TYPE] [-keystore URL]  
  53.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].  
  54.   -cacert         Import a CA's Trusted Certificate.  
  55.                     [-file FILE] [-storetype STORE_TYPE] [-keystore URL]  
  56.                     [-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].  
  57.   
  58. Standard options:  
  59.       -help       print this help, then exit  
  60.       -version    print version number, then exit  
  61.   -JOPTION        pass argument to the Java runtime  
  62.   
  63. Please report bugs at http://www.gnu.org/software/classpath/bugs.html  

 

 

 

javax.net.ssl

JAVA 加密技术

http://www.iteye.com/topic/426342

Java加密技术(一) 
Java加密技术(二) 
Java加密技术(三) 
Java加密技术(四) 
Java加密技术(五) 
Java加密技术(六) 
Java加密技术(七) 
Java加密技术(八) 
Java加密技术(九) 
Java加密技术(十)

HTTPS和HTTP的区别

http://jessicacao.iteye.com/blog/318912

http://bbs.5dmail.net/redirect.php?tid=184648&goto=lastpost

HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议 
它是一个安全通信通道,它基于HTTP开发,用于在客户计算机和服务器之间交换信息。它使用安全套接字层(SSL)进行信息交换,简单来说它是HTTP的安全版。 
它是由Netscape开发并内置于其浏览器中,用于对数据进行压缩和解压操作,并返回网络上传送回的结果。HTTPS实际上应用了Netscape的安全全套接字层(SSL)作为HTTP应用层的子层。(HTTPS使用端口443,而不是象HTTP那样使用端口80来和TCP/IP进行通信。)SSL使用 40 位关键字作为RC4流加密算法,这对于商业信息的加密是合适的。HTTPS和SSL支持使用X.509数字认证,如果需要的话用户可以确认发送者是谁。 
HTTPS和HTTP的区别: 
https协议需要到ca申请证书,一般免费证书很少,需要交费。 
http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议 
http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。 
http的连接很简单,是无状态的 
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全 
HTTPS解决的问题: 
1 . 信任主机的问题. 采用https 的server 必须从CA 申请一个用于证明服务器用途类型的证书. 改证书只有用于对应的server 的时候,客户度才信任次主机. 所以目前所有的银行系统网站,关键部分应用都是https 的. 客户通过信任该证书,从而信任了该主机. 其实这样做效率很低,但是银行更侧重安全. 这一点对我们没有任何意义,我们的server ,采用的证书不管自己issue 还是从公众的地方issue, 客户端都是自己人,所以我们也就肯定信任该server. 
2 . 通讯过程中的数据的泄密和被窜改 
1. 一般意义上的https, 就是 server 有一个证书. 
a) 主要目的是保证server 就是他声称的server. 这个跟第一点一样. 
b) 服务端和客户端之间的所有通讯,都是加密的. 
i. 具体讲,是客户端产生一个对称的密钥,通过server 的证书来交换密钥. 一般意义上的握手过程. 
ii. 加下来所有的信息往来就都是加密的. 第三方即使截获,也没有任何意义.因为他没有密钥. 当然窜改也就没有什么意义了. 
2. 少许对客户端有要求的情况下,会要求客户端也必须有一个证书. 
a) 这里客户端证书,其实就类似表示个人信息的时候,除了用户名/密码, 还有一个CA 认证过的身份. 应为个人证书一般来说上别人无法模拟的,所有这样能够更深的确认自己的身份. 
b) 目前少数个人银行的专业版是这种做法,具体证书可能是拿U盘作为一个备份的载体. 
HTTPS 一定是繁琐的. 
a) 本来简单的http协议,一个get一个response. 由于https 要还密钥和确认加密算法的需要.单握手就需要6/7 个往返. 
i. 任何应用中,过多的round trip 肯定影响性能. 
b) 接下来才是具体的http协议,每一次响应或者请求, 都要求客户端和服务端对会话的内容做加密/解密. 
i. 尽管对称加密/解密效率比较高,可是仍然要消耗过多的CPU,为此有专门的SSL 芯片. 如果CPU 信能比较低的话,肯定会降低性能,从而不能serve 更多的请求. 
ii. 加密后数据量的影响. 所以,才会出现那么多的安全认证提示

电信行业Http接口(通道)设计思路与实现过程

http://www.iteye.com/topic/398334

 

 

本页不但包含安全的内容,也包含不安全的内容.是否显示不安全的内容?

https中夹带有http的问题,

http://swingboat.iteye.com/blog/445608

今天解决了一个困扰我们很久的一个问题(说是很久,但一直没有花时间去research,想想不影响功能使用,没什么啊。而真正解决问题,也就那二十来分钟,哎!人已经懒惰成这样了)。
问题描述:
我们利用ajax做了一套系统,但通过https访问的时候,IE总会弹出下面的对话框:

而在我们的代码中所有的访问都是通过https的,怎么会有不安全的元素呢?在网上google了一下,有人提到可能是iframe的问题。而在我们系统中确实用到了很多的iframe。修改code,去掉所有的iframe。再次run,上面的对话框没有了,终于找到原因了。但是我们的系统中是需要iframe啊?请看下面的code:

1 var  iframe = document.createElement( " iframe " );
2          iframe.style.zIndex =- 1 ;
3          iframe.style.position = " absolute " ;
4          iframe.style.left = 0 ;
5          iframe.style.top = 0 ;
6          iframe.style.width = menu.getSize().x - 2 ;
7          iframe.style.height = menu.getSize().y - 4 ;
8          menu.getHtmlElement().appendChild(iframe);

从上面的code,可以看出代码中没有指定src属性,这样IE是没有办法知道这个iframe将引用的是安全内容还是不安全内容呢。所以会弹出上面的对话框。增加src属性,修改code:

var iframe=document.createElement("<iframe src='blank.html'>");//src是个只读属性,不能直接赋值,black.html是个空的静态页面。

再次run,对话框没有了,问题解决。

附录:

在IE下,如果div悬浮在select上面。select会透过div显示出来。这非常影响视觉效果。网上有很多的解决办法,其中一个就是在div中增加iframe。我们就是通过这个方法的,但又产生了这个问题。

 

 

md5

http://baike.baidu.com/view/7636.htm

 

MD5

目录
MD5简介
算法的应用
算法描述
具体的一个MD5实现
一些破解MD5的网站

 

 

  http://www.md5.com.cn (百万亿以上数据)
  http://www.cmd5.com
  http://www.xmd5.com 和http://www.xmd5.org 是一个网站(这三个网站都是国人做的)。
  http://md5.mmkey.com
  http://www.md5lookup.com/ (对数字破解比较好)
  http://md5.rednoize.com (对字母破解比较好)
  http://nz.md5.crysm.net (从1到4位数字)- 好像关了
  http://us.md5.crysm.net (美英字典的破解收集和IP地址)
  http://gdataonline.com (估计是基础字典的破解)
  http://www.hashchecker.com (这个倒是说得很厉害,但是在实际中,很多次我在这里都找不到)
  http://passcracking.ru
  http://www.milw0rm.com/md5
  http://plain-text.info (这个是我比较喜欢一个.也请你提交一些已破解的MD5)
  http://www.securitystats.com/tools/hashcrack.php (多种破解.我试过...没有一次破解出来.非常没用)
  http://www.schwett.com/md5/ - (破解挪威人(Norwegian)字典)
  http://passcrack.spb.ru/
  http://shm.pl/md5/
  http://www.und0it.com/
  http://www.neeao.com/md5/
  http://md5.benramsey.com/
  http://www.md5decrypt.com/
  http://md5.khrone.pl/
  http://www.csthis.com/md5/index.php
  http://www.md5decrypter.com/
  http://www.md5encryption.com/
  http://www.md5database.net/
  http://md5.xpzone.de/
  http://md5.geeks.li/
  http://www.hashreverse.com/
  http://www.cmd5.com/english.aspx
  http://www.md5.altervista.org/
  http://md5.overclock.ch/biz/index.php?p=md5crack&l=en
  http://alimamed.pp.ru/md5/ (如果你看不懂俄文,我告诉你,把你的MD5放到第2个格子)
  http://md5crack.it-helpnet.de/index.php?op=add (德国的....)
  http://cijfer.hua.fi/ (Projects->md5 reverse lookup)
  http://shm.hard-core.pl/md5/
  http://www.thepanicroom.org/index.php?view=cracker
  http://rainbowtables.net/services/results.php (我试过破过几次在这里)
  http://rainbowcrack.com/ (需要捐献)
  http://www.securitydb.org/cracker/ 
  http://passwordsecuritycenter.com/index.php?main_page=product_info&cPath=3&products_id=7 这个是证明他们的破解商品的质量..好让你来买这个破解程序...但是...只要能破解到即可.你又不一定要买..
  http://0ptix.co.nr/md5
  lm:
  http://sys9five.ath.cx:8080/hak5rtables/ 
  http://lasecwww.epfl.ch/~oechslin/projects/ophcrack/
  lm + ntlm:
  http://plain-text.info
  http://www.securitystats.com/tools/hashcrack.php
  http://rainbowtables.net/services/results.php 
  
 http://rainbowcrack.com/
  http://passwordsecuritycenter.com/index.php?main_page=product_info&cPath=3&products_id=7 
  md4:
  http://www.securitystats.com/tools/hashcrack.php
  http://rainbowtables.net/services/results.php 
  http://rainbowcrack.com/
  sha1:
  http://www.securitystats.com/tools/hashcrack.php
  http://passcrack.spb.ru/
  http://www.hashreverse.com/
  http://rainbowtables.net/services/results.php 
  http://rainbowcrack.com/
  http://www.md5encryption.com/
  http://passcracking.ru
  http://www.shalookup.com/ 

 

 

16位和32位密码查询

 

MD5:670B14728AD9902AECBA32E22FA4F6BD

解密:000000


md5(13851897759,32) = 7d3be18db14b452a11e4940ede114004
md5(13851897759,16) = b14b452a11e4940e

 

md5(18651665725,32) = 584285834b0032b2f809cde51228bb8e
md5(18651665725,16) = 4b0032b2f809cde5

 

md5(linezing.com,32) = be1fbc4210ef483dac295f1d7d424454
md5(linezing.com,16) = 10ef483dac295f1d

 

md5(kaixin001.com,32) = 1e0cca7301a54982fe7010c5a404d5bf
md5(kaixin001.com,16) = 01a54982fe7010c5

 

http://www.cmd5.com/

 

http://www.xmd5.org/

 

 


收录概况:
 

收录内容 是否收费
常用密码、网友奉献的明文密码 免费
1-5位大小写字母+数字 免费
6位小写字母 免费
6位大小写字母+数字 收费
7位数字 免费
7位小写字母+数字 收费
8位数字 免费
8位字母 收费
9-12位数字 收费

 

本站数据量不断增长中,是否收费可能也发生变动。

收录举例:

 

密码明文 说明
woshiniba “我是你爸”,没错,很多人就是用这个做密码,强烈bs。
zhoujielun “周杰伦”,明星,很多人顺手拿来做密码
zjl1234 “周杰伦1234”,加了数字照样可以查到!
mayingjiu “马英九”,不要以为你用它做密码很安全!
chenshuibian “陈水扁”,不要以为你用它做密码很安全!
13301010101 手机号码,全部可以查到
01062881234 北京的电话号码,全部可以查到
   

热门查询:

下面是查询较多的

admin888 469e80d32c0559f8
123456 49ba59abbe56e057
admin 7a57a5a743894a0e
111111 965eb72c92a549dd
123456 e10adc3949ba59abbe56e057f20f883e
admin 21232f297a57a5a743894a0e4a801fc3
  c65e114ded21a75b
000000 8ad9902aecba32e2
123456789 323b453885f5181f
12345678 83aa400af464c76d
123123 13955235245b2497
  4e909fc4cfd910bb
msmir 043f668459d83aae
  f1a38af5600c4ba8
  5b183d3c8b79f69b
123 ac59075b964b0715
888888 77804d2ba1922c33
  8cade77736368765
  3865512b48aa0e0a
123 202cb962ac59075b964b07152d234b70
123456789 25f9e794323b453885f5181f1b624d0b
  1c620a01bc338712
cccccc 6b490b3ecb4066b1
111111 96e79218965eb72c92a549dd5a330112
5201314 16e0c197e42a6be3
  511136c555647e8e
  0be93abb4dd831c2
  395839e41fe65599
123321 ff8aaa8a2dde9154
000000 670b14728ad9902aecba32e22fa4f6bd
  b4bb8eb9536548df
88888888 80f4189ca1c9d4d9
654321 1511b4f6020ec61d
  7bbd73250516f069
  93e853c0c3b2176e
  af5a630d06e9fd27
  164750fa6368334c
87742341 befd5a451518be7c
1234 52d04dc20036dbd8
  d35b08c903d65ca3
1234567890 f82d132f9bb018ca
user 9052e40b07aac0ca
  7fba6736f95a65d5
666666 c831b04de153469d
  8bda608cb00bcccb
admin888 7fef6171469e80d32c0559f88b377245
  5c86f8bd883edbbe
  f2cdfc31339c937f
  d41d8cd98f00b204e9800998ecf8427e
1234567 7412b5da7be0cf42
aisuhua 63a22ff2ce23fd32
  2a0cfd5de1c5970e
  664d117e1f56934b
  6ea31402d9656860
  c8bb891c23e1a4ee
  8f00b204e9800998
  bd9a9bd7daa7ec70
  63a2879064fe0e96
  6acb14aaa8c33eba
  ff22a6ce2021ac01
112233 757783e6cf17b26f
  4d9287164f38dde2
u88 ca105fe54f04781f
  9def65456fc2a68a
  88b346089154eae7
1 a0b923820dcc509a
fkuyygy e54c72aea6a17a51
  c1818c5b30a4ee4e
12345678 25d55ad283aa400af464c76d713c07ad
  7c02897c08550b0b
woaini 4b0db47d5f3e476a
111 9d8a121ce581499d
  fbcd4678e3c7b288
sxp750916 cbf76eed0e55cf43
  b8474564be2a76f5
qaz2324575 3daa9c6d91e704a22241e6a11f43d2a0
yejinfa df28256993c7b7eb
  d24b74525d30785d
  fb5dea26d8338782
5211314 eb03f6c72908fd84
1314520 4384298962649e58
  1d0066104956061b
123123 4297f44b13955235245b2497399d7a93
fengyun 2c7a8880ba4b1340
654321 c33367701511b4f6020ec61ded352059
11111111 60827015e5d605ed
  6c2a837fdc874433
82601628 d40badc0382a8f16
  ddd5a3cd645a3d6d
  83252964a2a30d2e
456123 c44da83eeafa3aeb
  ce34d0b608b3b45f
1 c4ca4238a0b923820dcc509a6f75849b
1234 81dc9bdb52d04dc20036dbd8313ed055
888888 21218cca77804d2ba1922c33e0151105
  a9d495b6e20cde2f
  15a1a9790140d714
  06dd87daabf43d31
  3cda31572e0509b4
19790919 3941e6262b1312e5

 

SSL

 

PKI

 

security

重放攻击 (Replay attack )是一种网络攻击,它恶意的欺诈性的重复或拖延正常的数据传输。

http://zh.wikipedia.org/wiki/%E9%87%8D%E6%94%BE%E6%94%BB%E5%87%BB

http://blog.csdn.net/jiangbin00cn/archive/2007/11/07/1872127.aspx

http://zhidao.baidu.com/question/50733410.html?fr=qrl

 

Java的简单MD5加密

http://ifanvip.iteye.com/blog/505475

 

 

/** 
 * MD5加密运算
 * @param str 要加密的字符串,不为null
 * @return result 加密后的MD5值
 */
public String getMD5(String str){
	 MessageDigest messageDigest = null;
	 try {
		messageDigest = MessageDigest.getInstance(&quot;MD5&quot;);
	
		messageDigest.reset(); // 重置,供再次使用
		
		messageDigest.update(str.getBytes(&quot;UTF-8&quot;));   // 使用指定的字节数组更新摘要,Char[]为编码为UTF-8			
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		byte[] byteArr = messageDigest.digest(); // 重置摘要,通过诸如填充之类的最终操作完成哈希计算
		
		StringBuffer md5Buffer = new StringBuffer();  // 构造一个字符串缓冲区,通过Append追加,装载加密后的值
		
		/*
		 * 下面涉及到位运算,不懂,研究中。。。
		 */

		for (int i = 0; i < byteArr.length; i++) {
			if (Integer.toHexString(0xFF & byteArr[i]).length() == 1) {
				md5Buffer.append("0").append(Integer.toHexString(0xFF & byteArr[i]));
			} else {
				md5Buffer.append(Integer.toHexString(0xFF & byteArr[i]));
			}
		}
		
		String result  = md5Buffer.toString();  //  从缓冲区得到运算结果
		
		return result;
		
		
	}
 

 

 

http://code.google.com/p/richinutil/source/browse/trunk/richinutil/src/org/richin/crypto/util/MD5Util.java?r=80

 

package org.richin.crypto.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 使用java.security.MessageDigest类写的一个工具类用来获取MD5码
 * @author Talen
 * @see java.security.MessageDigest
 */
public class MD5Util {
        /**  
        * 默认的密码字符串组合,apache校验下载的文件的正确性用的就是默认的这个组合  
        */  
        protected static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f' };  
        protected static MessageDigest messagedigest = null;  
        static{  
           try{  
            messagedigest = MessageDigest.getInstance("MD5");  
           }catch(NoSuchAlgorithmException nsaex){  
            System.err.println(MD5Util.class.getName()+"初始化失败,MessageDigest不支持MD5Util。");  
            nsaex.printStackTrace();  
           }  
        }  
         

        /**
             * 向getMD5方法传入一个你需要转换的原始字符串,将返回字符串的MD5码
             * @param code 原始字符串
             * @return 返回字符串的MD5码
             */
        public static String getMD5(String code) throws Exception {
                MessageDigest messageDigest = MessageDigest.getInstance("MD5");
                byte[] bytes = code.getBytes();
                byte[] results = messageDigest.digest(bytes);
                StringBuilder stringBuilder = new StringBuilder();

                for (byte result : results) {
                        //将byte数组转化为16进制字符存入stringbuilder中
                        stringBuilder.append(String.format("%02x", result));
                }

                return stringBuilder.toString();
        }
        /**  
        * 适用于上G大的文件  
        * @param file  
        * @return  
        * @throws IOException  
        */  
        public static String getFileMD5String(File file) throws IOException {  
           FileInputStream in = new FileInputStream(file);  
           FileChannel ch = in.getChannel();  
           MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());  
           messagedigest.update(byteBuffer);  
           return bufferToHex(messagedigest.digest());  
        }  
        private static String bufferToHex(byte bytes[]) {  
                   return bufferToHex(bytes, 0, bytes.length);  
                }  
                 
                private static String bufferToHex(byte bytes[], int m, int n) {  
                   StringBuffer stringbuffer = new StringBuffer(2 * n);  
                   int k = m + n;  
                   for (int l = m; l < k; l++) {  
                    appendHexPair(bytes[l], stringbuffer);  
                   }  
                   return stringbuffer.toString();  
                }  
                 
                 
                private static void appendHexPair(byte bt, StringBuffer stringbuffer) {  
                   char c0 = hexDigits[(bt & 0xf0) >> 4];  
                   char c1 = hexDigits[bt & 0xf];  
                   stringbuffer.append(c0);  
                   stringbuffer.append(c1);  
                }  
                 
                public static boolean checkPassword(String password, String md5PwdStr) {  
                   String s = getMD5String(password);  
                   return s.equals(md5PwdStr);  
                }  
                public static String getMD5String(String s) {  
                           return getMD5String(s.getBytes());  
                        }  
                         
                        public static String getMD5String(byte[] bytes) {  
                           messagedigest.update(bytes);  
                           return bufferToHex(messagedigest.digest());  
                        }  
        /** */
        /**
             * main方法用于测试
             */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                //字符'a'的MD5码是0cc175b9c0f1b6a831c399e269772661,如果是,则成功。
                try {
                        System.out.println(MD5Util.getMD5("a"));
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
} 

/*

Hide details

Change log
r80 by aslanchin on Nov 17, 2009   Diff

[No log message]

Go to: 	
Project members, sign in to write a code review

Older revisions
r45 by aslanchin on May 30, 2009   Diff
All revisions of this file

File info
Size: 3662 bytes, 109 lines
View raw file 

*/

 

 

重庆沙海硬件加密机

http://www.shahaiinfo.com/ourocx.jsp#

一、高安全性
       密码全程防护,全程不出现明文
       防御100%的已知的键盘钩子
       防止重放攻击、防止中间人篡改
       密钥安全:一次一密、非对称加密、私钥存储在服务器不可获取
       客户端核心模块工作在驱动层,客户端程序防反汇编,防脱壳技术,抗逆向分析

二、易用性 
       客户端可在浏览器窗口上自动安装、升级
       也有独立安装使用的一键点击安装包
       后台操作维护方便,基于HTTPS的WEB管理界面

三、高可用性
       支持HA,保证业务连续性
       沙海信息防护系统针对不同层次客户规模需求提供不同规格的产品供用户选择

四、兼容性
       支持WIN2000-WIN7全系列操作系统、IE5-IE8全系列浏览器
       全面兼容主流防病毒及防火墙软件
       兼容集中监控软件或实时监控平台

五、可审计性
       支持内部行为审计(管理员操作日志)
       支持外部行为审计(客户信息日志)
       支持回滚日志及远程SYSLOG日志服务器

 

 

 

 

 

 

安全编码规范

 

 

 

版本号:V2.4.2

 

 

 

 

 

 

 

 

 


 

目录

1       目标

2       安全编码原则

3       安全设计中的重要问题分布

4       安全编码规范

4.1        验证用户

1、身份验证

2、密码管理遵循的原则

4.2        保护敏感数据

1、前端保护敏感数据

2、后端保护敏感数据

3、传输保护

4.3        防止会话劫持和保护cookie

1、会话管理

2cookie管理

4.4        提供安全配置

4.5        验证输入

4.6        授权用户

4.7        访问控制

4.8        审核和记录活动和事件

1、错误处理

2、日志记录

4.9        数据库安全性

4.10          加密

4.11          输出编码

5       安全编码示例

5.1        输入验证和数据合法性校验

避免SQL注入

避免XML注入

避免跨站点脚本(XSS

5.2        声明和初始化

避免类初始化的相互依赖

5.3        表达式

不可忽略方法的返回值

不要引用空指针

使用Arrays.equals()来比较数组的内容

5.4        数字类型和操作

防止整数溢出

避免除法和取模运算分母为零

5.5        类和方法操作

数据成员声明为私有,提供可访问的包装方法

敏感类不允许复制

比较类的正确做法

不要硬编码敏感信息

验证方法参数

不要使用过时、陈旧或低效的方法

数组引用问题

不要产生内存泄露

5.6        异常处理

不要忽略捕获的异常

不允许暴露异常的敏感信息

不允许抛出RuntimeException, Exception,Throwable

不要捕获NullPointerException或其他父类异常

5.7        多线程编程

确保共享变量的可见性

确保共享变量的操作是原子的

不要调用Thread.run(),不要使用Thread.stop()以终止线程

确保执行阻塞操作的线程可以终止

相互依存的任务不要在一个有限的线程池执行

5.8        输入输出

程序终止前删除临时文件

检测和处理文件相关的错误

及时释放资源

5.9        序列化

不要序列化未加密的敏感数据

在序列化过程中避免内存和资源泄漏

反序列化要在程序最小权限的安全环境中

6       安全编码检查

6.1        输入和输出

6.2        API程序

6.3        跨站脚本

6.4        响应截断

6.5        重定向

6.6        SQL和数据库

6.7        SSL

6.8        会话管理

6.9        操作系统命令

6.10          记录

6.11          架构组件分析

6.12      JavaScript/XMLHTTP

 

 

 

 

 

 

 

 

1          目标

使用本规范可以实现:

1.      确定安全Web应用程序的重要体系结构和设计问题。

2.      设计时考虑重要部署问题。

3.      制定能增强Web应用程序输入验证的策略。

4.      设计安全的身份验证和会话管理机制。

5.      选择适当的授权模型。

6.      实现有效的帐户管理方法,并保护用户会话。

7.      对隐私、认可、防止篡改和身份验证信息进行加密。

8.      防止参数操作。

9.      设计审核和记录策略。

2          安全编码原则

1.      程序只实现指定的功能

2.      永不要信任用户输入,对用户输入数据做有效性检查

3.      必须考虑意外情况并进行处理

4.      不要试图在发现错误之后继续执行

5.      尽可能使用安全函数进行编程

6.      小心、认真、细致地编程

 

3          安全设计中的重要问题分布

列出了安全设计方法中必须解决的重要问题:验证用户、保护敏感数据、防止会话劫持和保护cookie、提供安全配置、验证输入、授权用户、访问控制、审核和记录活动和事件以及数据库安全。本文档分类总结归纳出解决以上重要问题必须遵循的一些基本原则,遵循基本原则可以很大程度地提高系统的安全性,减少漏洞,预防攻击。

 

1

 

4          安全编码规范

4.1      验证用户

1、身份验证

1、验证控制的执行代码放在服务器上

2、对所有的验证控件都使用一个集中的工具,包括调用外部认证服务的库

3、确保身份验证凭证不是以明文的形式在线传输的

4、保护身份验证 cookie

5、只使用HTTP POST请求发送身份验证凭据等敏感信息,只接受通过HTTP“POST”方法传递的信息,不可接受通过HTTP“GET”方法传递的信息

6、所有验证控件应该安全地失败

7、验证失败时进行模糊提示,失败响应不应该表明身份认证数据的哪一部分是不正确的的。例如,只是都使用无效的用户名和/或密码,而不是无效的用户名密码无效。显示界面和源代码中的错误响应必须是真正的一致。

8、对最终用户账户使用账户锁定策略:在无效登录尝试超过预定的次数(例如,五次尝试是最常见的)后强制将账户禁用或将事件写入日志。该账户必须禁用足够长的时间来阻止对凭证的蛮力猜测,但不应比允许执行拒绝服务攻击的时间更长(请注意,账户锁定策略不能用于拒绝服务攻击)

9、一个用户账号的最后一次使用(成功或不成功)应该在用户下次成功登录时报告给他们

10    、尽可能建立和利用标准的,被测试过的认证服务

2、密码管理遵循的原则

1、强制要求密码的长度。八个字符是常用的,但16更好或考虑使用多单词组成词组

2、在用户的屏幕上输入的密码被遮蔽(例如,基于Web形式使用密码输入型)

3、密码重置和更改的操作需要与创建账户和身份验证相同的控制水平,密码重置发生时通知用户,同时密码重置的问题应该支持足够随机的答案。(例如,最喜爱的书是一个坏问题,因为圣经是一个非常普通的答案)

4、临时密码和链接应该有一个短的到期时间,并在下次使用时强制执行临时密码的更改

5、防止密码重复使用

6、建议对密码字段禁用记住我功能

7、注意密码的储存,不要在用户存储中存储密码,将其加密储存在服务器上,一般它以保密性强的单向密码哈希被储存(不要使用MD5算法)。使用强密码,并将随机 salt 值与该密码结合。对于重要的系统入口,可有多个密码,如:管理员密码,管理认证码。分别把他们存放在不同的位置:数据库与文件中,这种多密码大大增强系统的安全性(其中对密码的加密方法,见下文的加密)

8、建议设置密码有效期:密码不应固定不变,而应作为常规密码维护的一部分,通过设置密码有效期对密码进行更改。在应用程序设计阶段,应该考虑提供这种类型的功能

 

4.2      保护敏感数据

1、前端保护敏感数据

1、cookie中不要存放敏感信息,所有敏感信息存放在服务器。如果保存了敏感数据,应该确保整个cookie加密

2、如果状态数据必须存储在客户端,在服务器端使用加密和完整性检查,以便跟踪状态篡改

3、对包含敏感信息的网页禁用客户端缓存

2、后端保护敏感数据

1、保护所有存储在服务器上的敏感数据的缓存或临时副本,对敏感数据执行适当的访问控制,以免来自未授权的访问所访问,一旦不再需要那些临时工作文件,就立即清除它们

2、应用程序应该支持对不再被需要的敏感数据的清除。(如个人资料或某些财务数据)

2、加密高度敏感的储存信息,如身份验证数据,即使在服务器端也要加密。并始终使用已审核好的算法

3、防止用户下载服务器端的源代码

5、删除不必要的应用程序和系统文件,因为这可以给攻击者揭示有用的信息

3、传输保护

1、不要在HTTP GET请求参数中包括敏感信息

2、实现对所有敏感信息的传输进行加密,这应包括用于保护连接的TLS和可能是由离散加密敏感文件的一个补充或基于非HTTP连接

3TLS证书应有效的(而不是过期的),并且有正确的域名

4、失败的TLS连接不应该回滚到一个不安全的连接

5、给所有连接指定字符编码

 

4.3      防止会话劫持和保护cookie

1、会话管理

1、确保会话ID足够复杂以满足相关强度的要求

2、检查会话是如何储存的:例如,在数据库,在内存中等,以确定其安全性,必要时可以进行加密

3、设置会话的HTTP闲置超时

4、当无效的会话ID出现时,应有相应的处理程序

5、会话标识符在服务器上创建

6、会话管理控制应该使用审核好的算法,以确保足够随机的会话标识符

7、对任何重新验证都要生成一个新的会话标识符

8、不允许同时登录相同的用户ID

9、建议为敏感操作附加除cookie之外的额外的强随机令牌,这种方法可以用来防止跨站请求伪造攻击

2cookie管理

1、为涉及敏感信息而保密要求高的cookie和保密性要求不高的cookie分别设置不同的域和路径

2、如果在登录前建立一个会话,关闭那个会话,并在成功登录后建立一个新会话

3、尽可能使用 SSL 保护会话身份验证 cookie,不要通过 HTTP 连接传递身份验证 cookie。在授权 cookie 内将其标记为安全的,那么它将只在浏览器和服务器通过https或其他安全协议链接时才被传输

4、将cookie设置为HttpOnly属性

 

4.4      提供安全配置

1、确保服务器,框架和系统组件运行批准的最新版本,并且有为使用的版本发行的所有补丁

2、关闭目录列表

3、限制Web服务器,进程和服务账户具有可能的最少特权

4、发生异常时,要安全地失败

5、删除所有不必要的功能和文件

6、在部署之前,删除测试代码或不打算用于生产上的任何功能

7、禁用不必要的HTTP方法,如WebDAV扩展。如果必需有一个支持文件处理的扩展的HTTP方法,那么要利用一个良好的审核认证机制

8、应用程序的安全配置存储应能以可读的形式输出,以便支持审计

9、实施一个软件变更控制系统来管理和记录在开发和生产中代码的变更

 

4.5      验证输入

1、在验证前将数据编码为一个共同的字符集,如UTF-8(规范化,标准化)。标准化是指将数据转化为标准形式的过程。文件路径和 URL 尤其倾向于标准化问题,许多广为人知的漏洞利用都直接源自标准化缺陷

2、验证预期的数据类型、范围、长度

3、使用服务器端代码执行其自身的验证。以免攻击者绕过客户端或关闭客户端脚本例程(例如,通过禁用 JavaScript 脚本)

4、所有的验证失败都导致输入拒绝,拒绝已知的有害的输入

5、在处理数据前,验证客户提供的所有数据,包括所有的参数。确保所有可以被恶意用户修改的输入,例如:HTTP头(例如cookies名称和值),URLs,输入字段,隐藏字段,下拉列表和其他Web组件,都被正确地验证。一定要包括从JavaScript,Flash或其他嵌入式代码的自动返回值

6、只要有可能,按照允许字符的白名单,对所有的输入进行验证:

如果任何有潜在危险的字符必须允许作为输入,确保执行了额外的控制来过滤输入。

常见的危险字符的例子包括:<>“”%()&+ \ \“\”

谨慎检查是否为空字节(00%),检查新行字符(\ R \ N0D0A);

检查--斜线.. / .. \)路径改变字符;

过滤输入示例:使用 URL 编码或 HTML 编码来包装数据,并将其作为文本而不是可执行脚本来处理。HtmlEncode 方法去除 HTML 字符,而 UrlEncode 方法对 URL 进行编码,使其成为有效的 URL 请求。

7、建议使用一个应用程序的集中输入验证例程,考虑集中式验证方法,例如,通过使用共享库中的公共验证和筛选代码。这可确保验证规则应用的一致性,此外,还能减少开发的工作量,且有助于以后的维护工作

 

4.6      授权用户

1、确保应用程序已明确定义了用户角色和其对应的权利

2、确保在操作中使用最少的特权,限制用户对系统级资源的访问

3、确保授权机制工作正常,安全地失败,并不能绕过

4、确保授权机制对每一个请求进行了检查

5、确保开发/调试的后门程序不在生产代码中出现,以免泄露敏感信息

6、实现最少的权限,限制用户只有对那些执行他们的任务所需要的功能,数据和系统信息具有权限

 

4.7      访问控制

1、只使用可信任的系统对象,如服务器端会话对象,来做访问授权的决策

2、访问控制应该安全失败

3、对于GET方式的请求,不能仅仅依赖“referer”头作为检查手段,因为它是可以被欺骗的。对于POST方式的请求,在通常范围内检查“referer”头可以保证一定程度的安全性

4、对每个请求执行授权控制,包括服务器端脚步制作的请求,还有来自富客户端技术如AJAXFlash的请求

5、限制只有被授权的用户才可以访问文件或其他资源,包括在应用程序的直接控制之外的资源

6、限制只有被授权的用户才可以访问被保护的URL和功能,访问服务、应用程序数据和与安全相关的配置信息(如果应用程序不能访问它的安全配置信息,那么拒绝所有的访问),以及进行直接对象引用

7、服务器端执行和表示层表示的访问控制规则必须匹配

8、限制单个用户或设备可以在一个给定的时间内执行的操作数量。操作/时间限制应高于实际业务需求,但也要足够的低,以防止自动攻击

9、如果允许长的身份验证会话,定期重新验证用户的授权,以确保他们的特权没有改变,如果特权改变了,注销用户,并迫使他们重新验证

10、实现账户的审计,强制禁用不可用的账户(例如,一个账户的密码到期后超过了30天)

11、应用程序必须支持账户的禁用(在系统受到威胁时使凭证失效或禁用账户,则可以避免遭受进一步的攻击),以及当授权终止时终止会话

12、服务账户或支持连接到/或来自外部系统的连接,应该被授予可能最少的特权

13、建议使用一个单一的站点范围内的组件检查访问授权

 

4.8     审核和记录活动和事件

1、错误处理

1、应用程序应该处理应用错误(而不是依赖于服务器的配置),使用不显示调试或堆栈跟踪信息的错误处理程序,在错误响应中不要泄露敏感信息,包括系统的详细信息,会话标识符或账户信息

2、确保应用程序是以安全的方式失败的

3、实施一般性错误消息,并使用自定义错误页面,确保异常和错误情况被正确的处理了,并正确释放分配的内存,释放资源

2、日志记录

1、所有的记录控制应该在一个可信任的系统(例如,服务器)上执行并且记录的控制应该支持指定的安全事件的成功和失败

2、确保日志中包含一些重要的日志的事件数据,但不要在日志中存放敏感信息,包括不必要的系统详细信息,会话标识符或密码

3、确保包括不可信任的数据的日志条目在预定的日志查看界面或软件中不会作为代码执行

4、限制只有授权的个人才可以访问日志,并且对所有的日志操作使用一个主程序

5、确保存在一种机制来进行日志分析

6、记录所有的输入验证失败

7、记录所有验证尝试,尤其是失败的

8、记录所有的访问控制失败的信息

9、记录所有明显的篡改事件,包括状态数据的异常改变

10、记录连接到无效或过期的会话令牌的尝试

11、记录所有系统异常

12、记录所有的行政职能,包括安全配置设置的更改

13、记录所有后端的TLS连接失败的信息

14、记录加密模块故障

15、使用加密哈希函数来验证日志条目的完整性

 

4.9     数据库安全性

1、使用强类型参数化查询

2、使用PreparedStatement预编译语句,传入的任何内容就不会和原来的语句发生任何匹配的关系

3、使用输入验证和输出编码,同时确保解决元字符。如果这些都失败了,不要运行数据库命令

4、应用程序访问数据库时,其应使用尽可能低水平的特权

5、对数据库访问使用加密连接

6、在应用程序中,连接字符串不应该使用硬编码。连接字符串应该储存在一个可信任的系统的单独的配置文件中,并且他们应该被加密。

7、使用储存过程来抽象数据访问

8、删除或更改所有默认的数据库管理密码。使用强密码或实施多因子身份认证

9、关闭所有不必要的数据库功能(例如,不必要的存储过程或服务,使用工具包,只安装最低要求的功能和选项设置(受攻击面减少))

10、禁用任何不需要的默认账户

11、建议应用程序应该为每个信任的区别(例如,用户、只读用户、访客、管理员)用不同的凭据连接到数据库

 

4.10加密

1、用来对应用程序用户保密的加密功能必须在一个可信任的系统上执行

2、对连接字符串进行加密,防止用户非法得到数据库连接密码

3、加密模块应该安全地失败

4、所有的随机数,随机文件名,随机GUID,以及随机字符串,当需要它们的随机值是不可猜测时,应该使用加密模块批准的随机数生成器产生

5、妥善管理加密密钥

6、不要自创加密方法,以免减弱保护能力

7、使用正确的算法和密钥大小,密钥越大,安全性越高

      数据加密标准:

         (DES)    64 位密钥(个字节);

        TripleDES 128 位密钥或 192 位密钥(16  24 个字节);

        AES    128位密匙、192位密匙或256位密匙(162432个字节);

        RSA    384 – 16,384 位密钥(48 – 2,048 个字节);

对于大量数据加密,应使用 TripleDES 对称加密算法;对于加密等级要求高,并且要高效快捷的加密一个区段时,应使用AES算法。要对将暂时存储的数据加密,可以考虑使用较快但较弱的算法,如 DES。对于数字签名,应使用 RSA  DSA 算法。对于哈希,应使用 SHA1 算法。对于用户键入的哈希,应使用基于哈希的消息验证(HMAC-SHA1)算法。

8、确保加密密钥的安全:使用 DPAPI 来回避密钥管理;定期回收密钥,以防密码的泄露。

 

4.11输出编码

1、  在受信任的系统上执行所有的编码(例如,服务器)

2、  对所有字符进行编码,除非他们被称为对web编译器是安全的

3、   对出站编码的每种类型都运用一个标准的,被测试过的方法:

输出的种类以及其对应的防御手段:

1)         支持HTML代码的输出:过滤。输出前要确保代码中不含有跨站攻击脚本。

2)         对不支持HTML的输出:HTML编码。在输出到页面前要进行HtmlEncode编码,部分服务器控件或者XSLT转换本身就支持HtmlEncode编码,可不必进行重复编码。

3)         对于URL的输出:URL编码。要对输出URL进行UrlEncode处理。

4)         页面内容的输出:转换特殊符号的编码形式,防止因特殊符号而出现错误,或跨站。

a.  对于js脚本的输出,要确保输出代码中不包含跨站脚本,注意“‘”“”“的输出,以免被组合成危险的js代码。

b.  对于style样式的输出,要确保样式的正确性。

c.  对于xml数据的输出,要确保数据中是否有XML不允许的字符,要对特殊字符进行转换才能输出。

 

5          安全编码示例(代码)

5.1      输入验证和数据合法性校验

程序接受数据可能来源于未经验证的用户,网络连接和其他不受信任的来源,如果未对程序接受数据进行校验,则可能会引发安全问题。

避免SQL注入

使用PreparedStatement预编译SQL,解决SQL注入问题,传递给PreparedStatement对象的参数可以被强制进行类型转换,确保在插入或查询数据时与底层的数据库格式匹配。 

public void doPrivilegedAction(

String username, char[] password

) throws SQLException {

Connection connection = getConnection();

if (connection == null) {

// Handle error

}

try {

String pwd = hashPassword(password);

// Ensure that the length of user name is legitimate

if ((username.length() > 8) {

// Handle error

}

String sqlString =

"select * from db_user where username=? and password=?";

PreparedStatement stmt = connection.prepareStatement(sqlString);

stmt.setString(1, username);

stmt.setString(2, pwd);

ResultSet rs = stmt.executeQuery();

if (!rs.next()) {

throw new SecurityException("User name or password incorrect");

}

// Authenticated, proceed

} finally {

try {

connection.close();

} catch (SQLException x) {

// forward to handler

}

}

}

 

 

使用存储过程

String custname = request.getParameter("customerName"); // This should REALLY be validated

 try {

        CallableStatement cs = connection.prepareCall("{call sp_getAccountBalance(?)}");

        cs.setString(1, custname);

        ResultSet results = cs.executeQuery();           

        // … result set handling

 } catch (SQLException se) {                      

        // … logging and error handling

 }

避免XML注入

通过StringBulider  StringBuffer 拼接XML文件时,需对输入数据进行合法性校验。

对数量quantity进行合法性校验,控制只能传入0-9的数字:

if (!Pattern.matches("[0-9]+", quantity)) {

    // Format violation

  }

  String xmlString = "<item>\n<description>Widget</description>\n" +

                     "<price>500</price>\n" +

                     "<quantity>" + quantity + "</quantity></item>";

  outStream.write(xmlString.getBytes());

  outStream.flush();

或者

class CustomResolver implements EntityResolver {

public InputSource resolveEntity(String publicId, String systemId)

throws SAXException, IOException {

// check for known good entities

String entityPath = "/home/username/java/xxe/file";

if (systemId.equals(entityPath)) {

System.out.println("Resolving entity: " + publicId +

" " + systemId);

return new InputSource(entityPath);

} else {

return new InputSource(); // Disallow unknown entities

// by returning a blank path

}

}

}

class XXE {

private static void receiveXMLStream(InputStream inStream,

DefaultHandler defaultHandler)

throws ParserConfigurationException, SAXException, IOException {

SAXParserFactory factory = SAXParserFactory.newInstance();

SAXParser saxParser = factory.newSAXParser();

// To set the Entity Resolver, an XML reader needs to be created

XMLReader reader = saxParser.getXMLReader();

reader.setEntityResolver(new CustomResolver());

reader.setErrorHandler(defaultHandler);

InputSource is = new InputSource(inStream);

reader.parse(is);

}

public static void main(String[] args)

throws ParserConfigurationException, SAXException, IOException {

receiveXMLStream(new FileInputStream("evil.xml"),

new DefaultHandler());

}

}

避免跨站点脚本(XSS

对产生跨站的参数进行严格过滤,禁止传入<SCRIPT>标签

//定义需过滤的字段串<script>

String s = "\uFE64" + "script" + "\uFE65";

// 过滤字符串标准化

s = Normalizer.normalize(s, Form.NFKC);

// 使用正则表达式匹配inputStr是否存在<script>

Pattern pattern = Pattern.compile(inputStr);

Matcher matcher = pattern.matcher(s);

if (matcher.find()) {

  // Found black listed tag

  throw new IllegalStateException();

} else {

  // ...

}

5.2      声明和初始化

避免类初始化的相互依赖

例:

错误的写法:

public class Cycle {

  private final int balance;

  private static final Cycle c = new Cycle();

  private static final int deposit = (int) (Math.random() * 100); // Random deposit

  public Cycle() {

    balance = deposit - 10; // Subtract processing fee

  }

  public static void main(String[] args) {

    System.out.println("The account balance is: " + c.balance);

  }

}

类加载时初始化指向Cycle类的静态变量c,而类Cycle的无参构造方法又依赖静态变量deposit,导致无法预期的结果。

正确的写法:

public class Cycle {

  private final int balance;

  private static final int deposit = (int) (Math.random() * 100); // Random deposit

  private static final Cycle c = new Cycle();  // Inserted after initialization of required fields

  public Cycle() {

    balance = deposit - 10; // Subtract processing fee

  }

 

  public static void main(String[] args) {

    System.out.println("The account balance is: " + c.balance);

  }

}

5.3      表达式

不可忽略方法的返回值

忽略方法的放回值可能会导致无法预料的结果。

错误的写法:

public void deleteFile(){

  File someFile = new File("someFileName.txt");

 someFile.delete();

}

正确的写法:

public void deleteFile(){

  File someFile = new File("someFileName.txt");

   if (!someFile.delete()) {

    // handle failure to delete the file

  }

}

 

或者

public class Replace {

public static void main(String[] args) {

String original = "insecure";

original = original.replace('i', '9');

System.out.println(original);

}

}

不要引用空指针

当一个变量指向一个NULL值,使用这个变量的时候又没有检查,这时会导NullPointerException

在使用变量前一定要做是否为NULL值的校验。

使用Arrays.equals()来比较数组的内容

数组没有覆盖的Object. equals()方法,调用Object. equals()方法实际上是比较数组的引用,而不是他们的内容。程序必须使用两个参数Arrays.equals()方法来比较两个数组的内容

public void arrayEqualsExample() {

  int[] arr1 = new int[20]; // initialized to 0

  int[] arr2 = new int[20]; // initialized to 0

  Arrays.equals(arr1, arr2); // true

}

5.4      数字类型和操作

防止整数溢出

使用java.lang.Number. BigInteger类进行整数运算,防止整数溢出。
 

publicclass BigIntegerUtil {

 

privatestaticfinal BigInteger bigMaxInt = BigInteger.valueOf(Integer.MAX_VALUE);

privatestaticfinal BigInteger bigMinInt = BigInteger.valueOf(Integer.MIN_VALUE);

 

publicstatic BigInteger intRangeCheck(BigInteger val) throws ArithmeticException {

if (val.compareTo(bigMaxInt) == 1 || val.compareTo(bigMinInt) == -1) {

thrownew ArithmeticException("Integer overflow");

        }

return val;

    }

 

publicstaticint addInt(int v1, int v2) throws ArithmeticException {

        BigInteger b1 = BigInteger.valueOf(v1);

        BigInteger b2 = BigInteger.valueOf(v2);

        BigInteger res = intRangeCheck(b1.add(b2));

return res.intValue();

    }

 

publicstaticint subInt(int v1, int v2) throws ArithmeticException {

        BigInteger b1 = BigInteger.valueOf(v1);

        BigInteger b2 = BigInteger.valueOf(v2);

        BigInteger res = intRangeCheck(b1.subtract(b2));

return res.intValue();

    }

 

publicstaticint multiplyInt(int v1, int v2) throws ArithmeticException {

        BigInteger b1 = BigInteger.valueOf(v1);

        BigInteger b2 = BigInteger.valueOf(v2);

        BigInteger res = intRangeCheck(b1.multiply(b2));

return res.intValue();

    }

 

publicstaticint divideInt(int v1, int v2) throws ArithmeticException {

        BigInteger b1 = BigInteger.valueOf(v1);

        BigInteger b2 = BigInteger.valueOf(v2);

        BigInteger res = intRangeCheck(b1.divide(b2));

return res.intValue();

}

}

避免除法和取模运算分母为零

要避免因为分母为零而导致除法和取模运算出现异常。

if (num2 == 0) {

  // handle error

} else {

 result1= num1 /num2;

result2= num1 % num2;

}

5.5      类和方法操作

数据成员声明为私有,提供可访问的包装方法

攻击者可以用意想不到的方式操纵publicprotected的数据成员,所以需要将数据成员为private,对外提供可控的包装方法访问数据成员。

敏感类不允许复制

包含私人的,机密或其他敏感数据的类是不允许被复制的,解决的方法有两种:

1、  类声明为final

final class SensitiveClass {

  // ...

}

2、  Clone 方法抛出CloneNotSupportedException异常

class SensitiveClass {

  // ...

  public final SensitiveClass clone()

throws CloneNotSupportedException {

    throw new CloneNotSupportedException();

  }

}

比较类的正确做法

如果由同一个类装载器装载,它们具有相同的完全限定名称,则它们是两个相同的类。

不正确写法:

// Determine whether object auth has required/expected class object

 if (auth.getClass().getName().equals(

      "com.application.auth.DefaultAuthenticationHandler")) {

   // ...

}

正确写法:

// Determine whether object auth has required/expected class name

 if (auth.getClass() == com.application.auth.DefaultAuthenticationHandler.class) {

   // ...

}

 

或者

// Determine whether objects x and y have the same class

if (x.getClass() == y.getClass()) {

// Objects have the same class

}

 

不要硬编码敏感信息

硬编码的敏感信息,如密码,服务器IP地址和加密密钥,可能会泄露给攻击者。

敏感信息均必须存在在配置文件或数据库中。

验证方法参数

验证方法的参数,可确保操作方法的参数产生有效的结果。不验证方法的参数可能会导致不正确的计算,运行时异常,违反类的不变量,对象的状态不一致。

对于跨信任边界接收参数的方法,必须进行参数合法性校验

private Object myState = null;

//对于修改myState方法的入参,进行非空和合法性校验

void setState(Object state) {

  if (state == null) {

    // Handle null state

  }

  if (isInvalidState(state)) {

    // Handle invalid state

  }

  myState = state;

}

不要使用过时、陈旧或低效的方法

在程序代码中使用过时的、陈旧的或低效的类或方法可能会导致错误的行为。

数组引用问题

某个方法返回一个对敏感对象的内部数组的引用,假定该方法的调用程序不改变这些对象。即使数组对象本身是不可改变的,也可以在数组对象以外操作数组的内容,这种操作将反映在返回该数组的对象中。如果该方法返回可改变的对象,外部实体可以改变在那个类中声明的 public 变量,这种改变将反映在实际对象中。

不正确的写法:

public class XXX {

         private String[] xxxx;

         public String[] getXXX() {

                            return xxxx;

         }

}

正确的写法:

public class XXX {

         private String[] xxxx;

         public String[] getXXX() {

                            String temp[] = Arrays.copyof();  // 或其他数组复制方法

                            return temp;

         }

}

不要产生内存泄露

垃圾收集器只收集不可达的对象,因此,存在未使用的可到达的对象,仍然表示内存管理不善。过度的内存泄漏可能会导致内存耗尽,拒绝服务(DoS)。

5.6      异常处理

不要忽略捕获的异常

对于捕获的异常要进行相应的处理,不能忽略已捕获的异常

不正确写法:

class Foo implements Runnable {

  public void run() {

    try {

      Thread.sleep(1000);

    } catch (InterruptedException e) {

      // 此处InterruptedException被忽略

    }

  }

}

正确写法:

class Foo implements Runnable {

  public void run() {

    try {

      Thread.sleep(1000);

    } catch (InterruptedException e) {

      Thread.currentThread().interrupt(); // Reset interrupted status

    }

  }

}

不允许暴露异常的敏感信息

没有过滤敏感信息的异常堆栈往往会导致信息泄漏,

不正确的写法:

try {

  FileInputStream fis =

      new FileInputStream(System.getenv("APPDATA") + args[0]);

} catch (FileNotFoundException e) {

  // Log the exception

  throw new IOException("Unable to retrieve file", e);

}

正确的写法:

class ExceptionExample {

  public static void main(String[] args) {

    File file = null;

    try {

      file = new File(System.getenv("APPDATA") +

             args[0]).getCanonicalFile();

      if (!file.getPath().startsWith("c:\\homepath")) {

log.error("Invalid file");

        return;

      }

    } catch (IOException x) {

log.error("Invalid file");

      return;

    }

    try {

      FileInputStream fis = new FileInputStream(file);

    } catch (FileNotFoundException x) {

log.error("Invalid file");

      return;

    }

  }

}

 

或者

class ExceptionExample {

public static void main(String[] args) {

FileInputStream fis = null;

try {

switch(Integer.valueOf(args[0])) {

case 1:

fis = new FileInputStream("c:\\homepath\\file1");

break;

case 2:

fis = new FileInputStream("c:\\homepath\\file2");

break;

//...

default:

System.out.println("Invalid option");

break;

}

} catch (Throwable t) {

MyExceptionReporter.report(t); // Sanitize

}

}

}

不允许抛出RuntimeException, Exception,Throwable

不正确的写法:

boolean isCapitalized(String s) {

  if (s == null) {

    throw new RuntimeException("Null String");

  }

}

 

private void doSomething() throws Exception {

  //...

}

正确写法:

boolean isCapitalized(String s) {

  if (s == null) {

    throw new NullPointerException();

  }

}

 

private void doSomething() throws IOException {

  //...

}

不要捕获NullPointerException或其他父类异常

不正确的写法:

boolean isName(String s) {

  try {

    String names[] = s.split(" ");

    if (names.length != 2) {

      return false;

    }

    return (isCapitalized(names[0]) && isCapitalized(names[1]));

  } catch (NullPointerException e) {

    return false;

  }

}

正确的写法:

boolean isName(String s) /* throws NullPointerException */ {

  String names[] = s.split(" ");

  if (names.length != 2) {

    return false;

  }

  return (isCapitalized(names[0]) && isCapitalized(names[1]));

}

5.7      多线程编程

确保共享变量的可见性

对于共享变量,要确保一个线程对它的改动对其他线程是可见的。

线程可能会看到一个陈旧的共享变量的值。为了共享变量是最新的,可以将变量声明为volatile或同步读取和写入操作。

将共享变量声明为volatile

final class ControlledStop implements Runnable {

  private volatile boolean done = false;

  @Override public void run() {

    while (!done) {

      try {

        // ...

        Thread.currentThread().sleep(1000); // Do something

      } catch(InterruptedException ie) {

        Thread.currentThread().interrupt(); // Reset interrupted status

      }

    }   

  }

  public void shutdown() {

    done = true;

  }

}

同步读取和写入操作:

final class ControlledStop implements Runnable {

  private boolean done = false;

  @Override public void run() {

    while (!isDone()) {

      try {

        // ...

        Thread.currentThread().sleep(1000); // Do something

      } catch(InterruptedException ie) {

        Thread.currentThread().interrupt(); // Reset interrupted status

      }

    }   

  }

  public synchronized boolean isDone() {

    return done;

  }

  public synchronized void shutdown() {

    done = true;

  }

}

确保共享变量的操作是原子的

除了要确保共享变量的更新对其他线程可见的,还需要确保对共享变量的操作是原子的,这时将共享变量声明为volatile往往是不够的。需要使用同步机制或Lock

同步读取和写入操作:

final class Flag {

  private volatile boolean flag = true;

  public synchronized void toggle() {

    flag ^= true; // Same as flag = !flag;

  }

  public boolean getFlag() {

    return flag;

  }

}

//使用读取锁确保读取和写入操作的原子性

final class Flag {

  private boolean flag = true;

  private final ReadWriteLock lock = new ReentrantReadWriteLock();

  private final Lock readLock = lock.readLock();

  private final Lock writeLock = lock.writeLock();

  public void toggle() {

    writeLock.lock();

    try {

      flag ^= true; // Same as flag = !flag;

    } finally {

      writeLock.unlock();

    }

  }

  public boolean getFlag() {

    readLock.lock();

    try {

      return flag;

    } finally {

      readLock.unlock();

    }

  }

}

不要调用Thread.run(),不要使用Thread.stop()以终止线程

确保执行阻塞操作的线程可以终止

public final class SocketReader implements Runnable {

  private final SocketChannel sc;

  private final Object lock = new Object();

  public SocketReader(String host, int port) throws IOException {

    sc = SocketChannel.open(new InetSocketAddress(host, port));

  }

  @Override public void run() {

    ByteBuffer buf = ByteBuffer.allocate(1024);

    try {

      synchronized (lock) {

        while (!Thread.interrupted()) {

          sc.read(buf);

          // ...

        }

      }

    } catch (IOException ie) {

      // Forward to handler

    }

  }

  public static void main(String[] args)

                          throws IOException, InterruptedException {

    SocketReader reader = new SocketReader("somehost", 25);

    Thread thread = new Thread(reader);

    thread.start();

    Thread.sleep(1000);

    thread.interrupt();

  }

}

相互依存的任务不要在一个有限的线程池执行

有限线程池指定可以同时执行在线程池中的线程数量的上限。程序不得使用有限线程池线程执行相互依赖的任务。可能会导致线程饥饿死锁,所有的线程池执行的任务正在等待一个可用的线程中执行一个内部队列阻塞

CPU饥饿案例一

AIX 检查系统日志是否cpu饥饿

Ecsvr3/user/IBM/WebSphere/AppServer6/profiles/EMALL03/logs/WCSCluster_emall03_mbr2$ grep  检测到 SystemOut*,看时间是在凌晨和早上,这时间应该在做批处理support,WAS SystemOut日志出现CPU饥饿错误,说明当时该两个节点处理负荷高,处理能力下降。

解决:相互依存的任务不要在一个有限的线程池执行 / 可能会导致线程饥饿死锁

有限线程池指定可以同时执行在线程池中的线程数量的上限。程序不得使用有限线程池线程执行相互依赖的任务。可能会导致线程饥饿死锁,所有的线程池执行的任务正在等待一个可用的线程中执行一个内部队列阻塞

CPU饥饿案例二

潘琦 880365 / C店查询场景 ,  CPU 饥饿问题:

解决:查询重复的冗余数据,导致数据库CPU高,进而导致其他WAS集群应用空闲饥饿状态,去掉就可以了 。

 

5.8      输入输出

程序终止前删除临时文件

检测和处理文件相关的错误

Java的文件操作方法往往有一个返回值,而不是抛出一个异常,表示失败。因此,忽略返回值文件操作的程序,往往无法检测到这些操作是否失败。Java程序必须检查执行文件I / O方法的返回值。

不正确的写法:

File file = new File(args[0]);

file.delete();

正确的写法:

File file = new File("file");

if (!file.delete()) {

log.error("Deletion failed");

}

及时释放资源

垃圾收集器无法释放非内存资源,如打开的文件描述符与数据库的连接。因此,不释放资源,可能导致资源耗尽攻击。

try {

  final FileInputStream stream = new FileInputStream(fileName);

  try {

    final BufferedReader bufRead =

        new BufferedReader(new InputStreamReader(stream));

 

    String line;

    while ((line = bufRead.readLine()) != null) {

      sendLine(line);

    }

  } finally {

    if (stream != null) {

      try {

        stream.close();

      } catch (IOException e) {

        // forward to handler

      }

    }

  }

} catch (IOException e) {

  // forward to handler

}

5.9      序列化

不要序列化未加密的敏感数据

序列化允许一个对象的状态被保存为一个字节序列,然后重新在稍后的时间恢复,它没有提供任何机制来保护序列化的数据。敏感的数据不应该被序列化的例子包括加密密钥,数字证书。

解决方法:

1、  对于数据成员可以使用transient,声明该数据成员是瞬态的。

2、  重写序列化相关方法writeObjectreadObjectreadObjectNoData,防止被子类恶意重写

class SensitiveClass extends Number {

  // ...

  protected final Object writeObject(java.io.ObjectOutputStream out) throws NotSerializableException {

    throw new NotSerializableException();

  }

  protected final Object readObject(java.io.ObjectInputStream in) throws NotSerializableException {

    throw new NotSerializableException();

  }

  protected final Object readObjectNoData(java.io.ObjectInputStream in) throws NotSerializableException {

    throw new NotSerializableException();

  }

}

在序列化过程中避免内存和资源泄漏

不正确的写法:

class SensorData implements Serializable {

  // 1 MB of data per instance!

   public static SensorData readSensorData() {...}

  public static boolean isAvailable() {...}

}

class SerializeSensorData {

  public static void main(String[] args) throws IOException {

    ObjectOutputStream out = null;

    try {

      out = new ObjectOutputStream(

          new BufferedOutputStream(new FileOutputStream("ser.dat")));

      while (SensorData.isAvailable()) {

        // note that each SensorData object is 1 MB in size

        SensorData sd = SensorData.readSensorData();

        out.writeObject(sd);

      }

    } finally {

      if (out != null) {

        out.close();

      }

    }

  }

}

正确写法:

class SerializeSensorData {

  public static void main(String[] args) throws IOException {

    ObjectOutputStream out = null;

    try {

      out = new ObjectOutputStream(

          new BufferedOutputStream(new FileOutputStream("ser.dat")));

      while (SensorData.isAvailable()) {

        // note that each SensorData object is 1 MB in size

        SensorData sd = SensorData.readSensorData();

        out.writeObject(sd);

        out.reset(); // reset the stream

      }

    } finally {

      if (out != null) {

        out.close();

      }

    }

  }

}

反序列化要在程序最小权限的安全环境中

6          安全编码检查(代码)

在开发的过程中,每个开发者能力与风格存在差异,为了保障软件开发质量,需要进行编码的安全检查,在安全编码检查过程中,需要对使用以下代码的部分进行重点检查。

6.1      输入和输出

以下读取数据的应用程序,可以导致路径转义和DOS服务攻击风险。

Java.io

java.util.zip

java.util.jar

FileInputStream

ObjectInputStream

FilterInputStream

PipedInputStream

SequenceInputStream

StringBufferInputStream

BufferedReader

ByteArrayInputStream

CharArrayReader

File

ObjectInputStream

PipedInputStream

StreamTokenizer

getResourceAsStream

java.io.FileReader

java.io.FileWriter

java.io.RandomAccessFile

java.io.File

java.io.FileOutputStream

mkdir

renameTo

 

6.2      API程序

使用以下API程序,导致HTTP请求中存在等安全风险。

javax.servlet.*

getParameterNames

getParameterValues

getParameter

getParameterMap

getScheme

getProtocol

getContentType

getServerName

getRemoteAddr

getRemoteHost

getRealPath

getLocalName

getAttribute

getAttributeNames

getLocalAddr

getAuthType

getRemoteUser

getCookies

isSecure

HttpServletRequest

getQueryString

getHeaderNames

getHeaders

getPrincipal

getUserPrincipal

isUserInRole

getInputStream

getOutputStream

getWriter

addCookie

addHeader

setHeader

setAttribute

putValue

javax.servlet.http.Cookie

getName

getPath

getDomain

getComment

getMethod

getPath

getReader

getRealPath

getRequestURI

getRequestURL

getServerName

getValue

getValueNames

getRequestedSessionId

 

 

6.3      跨站脚本

使用以下代码,可能导致出现跨站脚本风险。

javax.servlet.ServletOutputStream.print

javax.servlet.jsp.JspWriter.print

java.io.PrintWriter.print

 

6.4      响应截断

使用以下代码,可以导致出现HTTP响应截断风险。

javax.servlet.http.HttpServletResponse.sendRedirect

addHeader, setHeader

 

6.5      重定向

使用以下代码,可以导致出现URL重定向风险。

sendRedirect

setStatus

addHeader, setHeader

 

6.6      SQL和数据库

使用以下SQL语言与代码,可以导致出现SQL注入和数据库操纵风险。

jdbc

executeQuery

select

insert

update

delete

execute

executestatement

createStatement

java.sql.ResultSet.getString

java.sql.ResultSet.getObject

java.sql.Statement.executeUpdate

java.sql.Statement.executeQuery

java.sql.Statement.execute

java.sql.Statement.addBatch

java.sql.Connection.prepareStatement

java.sql.Connection.prepareCall

 

 

6.7       SSL

使用以下代码,可以导致出现SSL相关风险。

com.sun.net.ssl

SSLContext

SSLSocketFactory

TrustManagerFactory

HttpsURLConnection

KeyManagerFactory

 

6.8      会话管理

使用以下代码,可以导致出现会话管理安全风险。

getSession

invalidate

getId

 

6.9      操作系统命令

使用以下代码,可以导致出现执行操作系统命令风险。

java.lang.Runtime.exec

java.lang.Runtime.getRuntime

 

6.10   记录

java.io.PrintStream.write

log4j

jLo

Lumberjack

MonoLog

qflog

just4log

log4Ant

JDLabAgent

 

6.11   架构组件分析

使用以下架构组件,跟踪组件版本可以发现已知风险。

### Ajax

XMLHTTP

 

### Struts

org.apache.struts

 

### Spring

org.springframework

 

### Java Server Faces (JSF)

import javax.faces

 

### Hibernate

import org.hibernate

 

### Castor

org.exolab.castor

 

### JAXB

javax.xml

 

### JMS

JMS

 

6.12   JavaScript/XMLHTTP

使用以下JavaScript,操纵用户状态或控制浏览器可能导致风险。

eval

document.cookie

document.referrer

document.attachEvent

document.body

document.body.innerHtml

document.body.innerText

document.close

document.create

document.createElement

document.execCommand

document.forms[0].action

document.location

document.open

document.URL

document.URLUnencoded

document.write

document.writeln

location.hash

location.href

location.search

window.alert

window.attachEvent

window.createRequest

window.execScript

window.location

window.open

window.navigate

window.setInterval

window.setTimeout

window.createRequest

 

 

 

7          安全编码规范细则(功能)

 

7.1      验证用户

1、身份验证

编号

1

类型

 

名称

持续恶意注册

安全风险

持续恶意注册唯一性账户,导致唯一性账户收益被侵占

安全要求

对有注册有收益的唯一性账户进行身份验证

案例

在手机客户端进行注册,没有对手机注册账户进行身份验证,导致恶意注册,并利用手机新注册用户收益进行消费。

 

编号

2

类型

 

名称

持续恶意登录

安全风险

对暴露对外的接口,要考虑会用于黑客的扫描。

安全要求

加入校验码,增加扫描成本

采用ip地址黑名单策略。

案例

手机终端支付宝登陆(扫描)

 

编号

3

类型

 

名称

内部URL白名单

安全风险

该白名单,都在程序员手中维护,没有评审流程。

 

安全要求

此类白名单,需要走评审流程。严格控制。

案例

付宝-白名单。很多不应该被外网不登陆访问的地址,加在了白名单中

 

 

 

2、密码管理遵循的原则

编号

1

类型

 

名称

密码长度

安全风险

密码破解

安全要求

互联网用户密码6

企业用户密码8

管理员密码8

案例

 

 

编号

2

类型

 

名称

密码复杂度

安全风险

密码排列简单,导致被猜测破解

安全要求

企业普通用户密码大小写字符、数字

管理员权限密码必须增加特殊符号

案例

 

 

编号

3

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

编号

4

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

 

7.2      保护敏感数据

1、前端保护敏感数据

 

编号

1

类型

 

名称

使用合适的方式提交数据请求

安全风险

GET方式提交表单,表单中的参数会在浏览器地址栏中显示,而且浏览器不会控制表单提交的刷新操作。在浏览器中显示表单参数,容易造成恶意用户欺骗对电脑安全不熟悉的用户复制带参数的URL供他人使用。

 

安全要求

使用post方式提交

案例

支付宝-余额提醒,余额验证,余额查询,绑定手机,修改绑定手机

综合金融-保险

购物主站等

 

编号

2

类型

 

名称

未使用支付安全控件

安全风险

电子书在调用付宝支付时候未使用安全控件

彩票等虚拟在调用支付宝支付时候未使用安全控件

安全要求

在调用付宝进行付时,必须使用了付宝提供的安全控件。

案例

 

 

编号

 

类型

 

名称

促销活动优惠卷号字段安全规则

处理规则

卷号ID、卷密码,

卷号ID长度,现在长度为12位数字,增加长度,18

卷号ID排列顺序,不按照固定序列发送。

卷号ID复杂度,不使用简单ID序列。

卷密码长度,从6位数字,增加到12

卷密码复杂度,从纯数字,增加大小写字符、数字。

示例

 

组成规则

卷号ID

卷号(18位)

ysiemwj1ju381WPkUv

 

卷密码(12)

Q9Ks18JWs2ag

 

编号

 

类型

 

名称

礼品卡号字段安全规则

处理规则

礼品卡ID、卷密码,

礼品卡ID长度,现在长度为10位数字,增加长度18

礼品卡ID排列顺序,不按照固定序列发送。

礼品卡ID复杂度,不使用简单ID序列。

礼品卡密码长度,从6位数字,增加到12

卷密码复杂度,从纯数字,增加大小写字符、数字。

示例

 

组成规则

礼品卡ID

礼品卡(18位)

ysiemwj1ju381WPkUv

 

卷密码(12)

Q9Ks18JWs2ag

 

2、后端保护敏感数据

编号

3

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

编号

3

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

 

3、传输保护

编号

1

类型

 

名称

协议加密

安全风险

明文传输信息截取,用户名、密码嗅探

安全要求

采用SSL加密协议

案例

 

 

编号

2

类型

 

名称

密钥安全

安全风险

密钥存储、密钥长度、密钥复杂度都可能存在安全风险

安全要求

 

 

 

 

7.3      防止会话劫持和保护cookie

编号

1

类型

 

名称

cookie篡改

安全风险

Cookie没有做加密处理,导致易被篡改。黑客篡改cookie后,可以模拟登录等。

安全要求

cookie中做加密处理。

案例

商旅机票项目中发现存在cookie篡号风险,如果cookie中存在以"WC_USERACTIVITY_"开头的字段将被服务器认为已登录状态。通过篡改cookie将可模拟登录。

广告联盟-通过修改Cookie中的用户ID

社区cookie可修改可恶意晒单

 

编号

2

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

 

 

 

7.4      提供安全配置

编号

1

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

编号

2

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

 

7.5      验证输入

 

编号

1

类型

 

名称

文件上传

安全风险

脚本文件上传,执行操作系统命令

安全要求

采用白名单控制上传文件类型

采用文件数据流类型进行传输

限制存放上传文件的操作系统目录权限,关闭上传文件目录执行权限

限制上传文件大小

限制上传文件存放路径

限制上传后文件名称,禁止采用文件简单命名规则,可采用上传文件时间散列作为规则命名

禁止直接显示文件绝对路径

案例

校园箐英网

 

 

编号

2

类型

 

名称

文件下载

安全风险

访问非授权路径,下载非授权文件

安全要求

限制下载文件访问路径

进制在直接显示文件绝对路径

采用白名单控制下载文件类型

 

案例

 

 

编号

3

类型

 

名称

关键信息通过URL/hidden传递,后台没校验

安全风险

把关键业务数据直接通过hidden字段或URL传递,给黑客留下了篡改的后门。关键信息一定要从后台去取。

安全要求

关键的信息,一定沟通后台去取,比如价格,用户ID等。前台是易给篡改的,是不安全的。

案例

付宝-会员绑定手机(户头号),庆幸的是传递的过程加了签名,黑客不好篡改,不过漏洞还是必须堵上。

付宝-邮箱找回支付密码-输入证件号,提交新支付密码。通过url传递了证件号,userid关键信息。

论坛系统生成静态页的接口callBackUrl没有验证参数是否为本站URL,若不校验将会跳转至恶意网站。

物流服务组中的接口存在大量参数,只对订单号、SAP单号进行了校验,其他的参数均未校验,不校验的参数很容易被篡改。

促销系统通过urlactivity_name,可以使用无限抽的活动在回头客中抽奖。

促销阶梯团购报名提交,通过修改url中的商品Id获得此地区不销售的商品的团购资格

 

编号

4

类型

 

名称

输入未经验证

安全风险

服务端未对客户端输入的数据进行类型、范围、长度等方面的安全验证。

安全要求

在逻辑处理之前,验证客户端提供的所有数据,包括参数、URLHTTP头信息(比如:cookie名称和数值)。此外,还需要检查是否存在潜在危险的特殊字符,如:<> " ' % ( ) & + \ \' \"

 

案例

商旅机票项目未对用户名、密码作长度限制。

购物主站,开发平台等

 

编号

5

类型

 

名称

数据类型定义不当

安全风险

金额计算没有对临界点做处理,有些特殊金额可能会出现金额精度缺失

安全要求

资金计算与处理必须使用Money类,而不允许使用浮点数(如double/float等)。

案例

商旅机票项目中发现存在此问题,导致精度缺失。

综合金融

 

编号

6

类型

 

名称

链接/接口的安全策略不当

安全风险

链接/接口设计上本不应该被外网返回,不过却暴露给外网。

安全要求

不应该被外网访问的接口务必不能暴露给外网。

案例

论坛系统中JOB用接口不应该被外网访问却暴露给外网。

 

编号

7

类型

 

名称

支付完成后校验,未校验金额

安全风险

对支付完成后校验,没有校验金额,只校验了交易是否成功。

安全要求

对调用付宝的支付,接收付宝回调的时候,1要校验成功与否,2要校验金额。才能判断是否是支付成功

案例

电子书-快捷支付回调

 

编号

8

类型

 

名称

存在XSS攻击可能性

安全风险

没有对输入进行校验,存在输入脚本可能性。

 

安全要求

前端对脚本进行过滤,禁止用户输入。

案例

开放平台-sop-修改子用户等

 

 

编号

9

类型

 

名称

多次连续提交数据

安全风险

未对数据提交频率进行限制,导致数据连续多次恶意提交

安全要求

限制数据提交频率,设置数据发送时间间隔

对各类POST类型方法,限制提交频。

例如:在注册、登录、密码找回、留言、订单等限制提交频率。

使用验证码或者延迟倒计时器

案例

 

 

编号

10

类型

 

名称

优惠卷\礼品卡输入安全规则

处理规则

限制数据提交频率,设置数据发送时间间隔

1.       使用验证码

在输入优惠卷号、密码之外,增加验证码输入。防止自动化提交数据。

当前输入光标位于验证码输入栏内,验证码栏自动刷新一次。

2.       使用延迟倒计时器

在输入的过程中将根据输入出错的次数,增加间隔。

每次输入优惠卷及密码,如果输入的卷号和密码错误,都必须间隔1分钟。届时输入按钮将变不可用,并在按钮上,出现倒计时器。

 

示例

例如:

1.  促销活动优惠卷号。在输入卷号、密码同时、必须输入当前随机验证码。

当输入光标进入验证码栏时,验证码栏将自动刷新。

假设原先显示验证码为“QU59ay”,将会自动刷新位“J3SPtx

2.       促销活动优惠卷号。在输入的过程中将根据输入出错的次数,增加间隔。

输入错误优惠卷号及密码,1小时内,累计10次后,将被禁止15分钟内输入。

输入错误优惠卷号及密码,6小时内,累计30次后,将被禁止12小时内输入。

输入错误优惠卷号及密码,12小时内,累计50次后,将被禁止24小时内输入。

 

组成规则

 

 

 

 

 

编号

10

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

 

7.6      授权用户

 

编号

1

类型

 

名称

用户未经登录就可进行业务操作

安全风险

由于登录信息是维护在主站上,其他分站点是采用信任登录的形式和主站合作。所以进行业务操作时,必须验证用户的登录信息。所以需要分站点,在提供出业务接口时候,包含useridsessionid,在业务操作前先验证用户是否登录。

安全要求

对相应业务操作前须对用户进行身份验证,禁止未登录用户进行操作。

案例

酒店现付酒店预订、查询订单时手机终端直接传递用户信息,服务端没有做用户信息验证,将导致未登录的用户也可进行业务操作。

 

编号

2

类型

 

名称

操作时未校验是否是本人订单

安全风险

对外暴露的接口可以查询删除修改订单内容的,必须校验该订单是否是登录人的。否则存在轻者信息泄露,重者资料被修改,订单被取消等风险。

安全要求

对用户进行身份验证,对非本人的订单不允许有任何访问与操作,必要时需对订单进行加签。验证身份时的userid,通过session去取,勿通过url拼接传递。

案例

酒店现付查询酒店订单、取消订单时只判断了用户是否登录,没有判断当前用户与该订单的关系,订单将会被其他用户查看泄露个人隐私,或者订单被恶意取消。

销售组一键购设置时没有判断当前用户,可以任意查看、修改或取消别人的订单。

团购频道付宝支付、订单退款、订单取消、订单详情页面给用户发送短信时未对订单身份及订单ID验证;并且在使用付宝余额支付时密码明文传输,通过抓包即可获取密码,危险性极高。

礼品订单-虚拟订单-订单查询

开放平台很多接口,如撤销相关发票和结算清单等,都没有校验是否本人

 

 

 

 

 

 

 

7.7      访问控制

 

编号

1

类型

 

名称

用户权限验证错误

安全风险

某些功能必须特殊的权限才能访问,不过由于设计或程序上却是,造成了权限未经验证或验证不当。

安全要求

产品设计和研发人员,共同确定角色权限范围,进行修复。

案例

开发平台角色管理等权限验证错误

 

 

编号

3                 

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

 

7.8      审核和记录活动和事件

编号

1

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

编号

3

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

 

7.9      数据库安全性

编号

1

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

编号

3

类型

 

名称

 

安全风险

 

安全要求

 

案例

 

 

 

 

7.10   加密

编号

1

类型

 

名称

密钥明文存放(代码,数据库,文件中)

安全风险

密钥写死在代码中,或明文存放在数据里,或存在服务器的文件里。造成密钥易被内部泄露。

安全要求

a)      密钥需统一管理

b)       采用加密机方案

案例

付宝-查询余额,修改绑定手机,邮箱找回支付密码等,这是普遍问题将统一解决。

 

编号

2

类型

 

名称

接口未加密加签

安全风险

对能够修改/新增/删除数据的接口,一定要签名,数据要加密尤其是密码,卡号等敏感信息,并记录操作日志。

安全要求

如非特殊原因,除非接口非常简单非常安全,对外暴露的接口必须进行签名防篡,对特殊信息加密,并记录操作记录日志。

案例

商旅机票VGS调用不夜城接口、不夜城推送VGS接口未采用动态验签,接口存在安全隐患,不加签的接口可能会被恶意调用。

酒店团购余额支付校验接口未加密,加签,并且未使用HTTPS访问,并支付密码明文传递,存在很大风险性。

彩票的竞彩足球代购确认,北单合买代购等,密码http,明文,未加密加签

酒店团购的其他对外接口也没有加密,加签。

开放平台的接口都没加密,加签

 

编号

3

类型

 

名称

未脱密处理

安全风险

是否已经保证所有的关键信息不被泄露,证件号码、银行帐号、银行帐号、手机号码等,对关键数据要脱密处理

安全要求

全部采用规范的脱密处理

案例

手机号显示前三后一,如135*******5

邮箱隐藏@前挨着的两位,如120707**@cns****.com

证件号显示前一后一,如4****************4

姓名显示第一位,其余隐藏,如张**

酒店,展现信息

 

 

编号

1

类型

 

名称

手机号安全显示

处理规则

显示前3位和最后2位,其他以实际位数替换为星号

示例

150******66

组成规则

3位运营商代码4位归属地代码4位随机码

 

编号

2

类型

 

名称

身份证号安全显示

处理规则

显示前1位和最后1位,其他以实际位数替换为星号

示例

2****************8

组成规则

6位地区码8位出生码2位顺序码1位性别码1位校验码

 

 

编号

3

类型

 

名称

客户姓名安全显示

处理规则

显示前1位,其他以实际位数替换为星号

示例

*

组成规则

2-6

 

编号

4

类型

 

名称

银行卡号安全显示

处理规则

显示最后4位,其他位数缩略为2个星号并置前

示例

**4497招商银行

组成规则

6位发行者标识代码9-12位个人账号标识1位校验码

 

编号

5

类型

 

名称

电子邮箱安全显示

处理规则

显示前2位和最后1位用户名,一律按固定位数(全长6位)进行填充

示例

wi***t@vip.qq.com

组成规则

用户名@域名

 

 

7.11   输出编码

 

编号

1

类型

 

名称

编码统一

安全风险

不一致编码,可能导致攻击方法绕过安全策略

安全要求

采用统一编码定义,例如网站编码都采用utf-8,输出都转换为utf-8,非utf-8字符统一定义。

案例

 

 

 

 

 

<!DOCTYPE HTML>
<html lang="en-US">

<head>
<meta name="keywords" content="" />
<meta name="description" content="" />
<script src="/portal/RES/soaNewStyle/original/js/jquery.js"></script>
<link type="text/css" href="http://oa.cns*****.com/infoResource/news/portal/soaNST/soaNST3/css/soa.article.css" rel="stylesheet">
<link type="text/css" href="http://oa.cns*****.com/infoResource/news/portal/soaNST/soaNST3/css/soa.aside.css" rel="stylesheet">
<link type="text/css" href="http://oa.cns*****.com/infoResource/news/portal/soaNST/soaNST3/css/soa.public.css" rel="stylesheet">
<script src="http://oa.cns*****.com/infoResource/news/portal/soaNST/soaNST3/js/jquery.js"></script>
<title>欢迎访问**内部门户</title>
<link rel="shortcut icon" href="/portal/RES/css/images/favicon.ico" type="image/x-icon" />
<link disabled="true" charset="gb2312" title="defualt" href="skin/default/datepicker.css" type="text/css" rel="stylesheet">
</head>
<body>
、、、
</body>
</html>

 
 

 

 

 

ddd

JAVA中简单调用MD5算法进行加密.

http://yuelangyc.iteye.com/blog/967263

D:\workspace\test\src\com\iteye\lindows\test\MD5Test.java

package com.iteye.lindows.test;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author Lindows
 */
public class MD5Test {
	public static byte[] getKeyedDigest(byte[] buffer, byte[] key) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(buffer);
			return md5.digest(key);
		} catch (NoSuchAlgorithmException e) {
		}
		return null;
	}

	public static String getKeyedDigest(String strSrc, String key) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(strSrc.getBytes("UTF8"));
			String result = "";
			byte[] temp;
			temp = md5.digest(key.getBytes("UTF8"));
			for (int i = 0; i < temp.length; i++) {
				result += Integer.toHexString(
						(0x000000ff & temp[i]) | 0xffffff00).substring(6);
			}
			return result;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void main(String[] args) {
		String MD5Created = null;
		String s = "000000";
		// 下面第二个参数请填空字符串
		MD5Created = MD5Test.getKeyedDigest(s, "");
		System.out.println("key:" + s + ",md5:" + MD5Created);
		// key:000000,md5:670b14728ad9902aecba32e22fa4f6bd
	}
}

 

HTTP使用BASIC认证的原理及实现方法 

http://blog.itpub.net/23071790/viewspace-709367/

一.   BASIC认证概述

HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份证的方法,当一个客户端向HTTP服务 器进行数据请求时,如果客户端未被认证,则HTTP服务器将通过基本认证过程对客户端的用户名及密码进行验证,以决定用户是否合法。客户端在接收到HTTP服务器的身份认证要求后,会提示用户输入用户名及密码,然后将用户名及密码以BASE64加密,加密后的密文将附加于请求信息中, 如当用户名为anjuta,密码为:123456时,客户端将用户名和密码用合并,并将合并后的字符串用BASE64加密为密文,并于每次请求数据 时,将密文附加于请求头(Request Header)中。HTTP服务器在每次收到请求包后,根据协议取得客户端附加的用户信息(BASE64加密的用户名和密码),解开请求包,对用户名及密码进行验证,如果用 户名及密码正确,则根据客户端请求,返回客户端所需要的数据;否则,返回错误代码或重新要求客户端提供用户名及密码。

 

二.   BASIC认证的过程

1.  客户端向服务器请求数据,请求的内容可能是一个网页或者是一个其它的MIME类型,此时,假设客户端尚未被验证,则客户端提供如下请求至服务器:

Get /index.html HTTP/1.0
Host:www.google.com

2.  服务器向客户端发送验证请求代码401,服务器返回的数据大抵如下:

HTTP/1.0 401 Unauthorised
Server: SokEvo/1.0
WWW-Authenticate: Basic realm="google.com"
Content-Type: text/html
Content-Length: xxx

3.  当符合http1.01.1规范的客户端(如IEFIREFOX)收到401返回值时,将自动弹出一个登录窗口,要求用户输入用户名和密码。

4.  用户输入用户名和密码后,将用户名及密码以BASE64加密方式加密,并将密文放入前一条请求信息中,则客户端发送的第一条请求信息则变成如下内容:

Get /index.html HTTP/1.0
Host:www.google.com
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxx

注:xxxx....表示加密后的用户名及密码。

5.  服务器收到上述请求信息后,将Authorization字段后的用户信息取出、解密,将解密后的用户名及密码与用户数据库进行比较验证,如用户名及密码正确,服务器则根据请求,将所请求资源发送给客户端:

 

三.         BASIC认证的缺点

HTTP基本认证的目标是提供简单的用户验证功能,其认证过程简单明了,适合于对安全性要求不高的系统或设备中,如大家所用路由器的配置页面的认证,几乎 都采取了这种方式。其缺点是没有灵活可靠的认证策略,如无法提供域(domainrealm)认证功能,另外,BASE64的加密强度非常低,可以说仅 能防止sohu的搜索把它搜到了。当然,HTTP基本认证系统也可以与SSL或者Kerberos结合,实现安全性能较高(相对)的认证系统

 

四.         BASIC认证的JAVA实现代码

 

HttpSession session=request.getSession();

         String user=(String)session.getAttribute("user");

         String pass;

         if(user==null){

             try{

                response.setCharacterEncoding("GBK");

                PrintWriter ut=response.getWriter();

                String authorization=request.getHeader("authorization");

                if(authorization==null||authorization.equals("")){

                    response.setStatus(401);

                    response.setHeader("WWW-authenticate","Basic realm=\"请输入管理员密码\"");

                    out.print("对不起你没有权限!!");

                    return;

                }

                String userAndPass=new String(new BASE64Decoder().decodeBuffer(authorization.split(" ")[1]));

                if(userAndPass.split(":").length<2){

                    response.setStatus(401);

                    response.setHeader("WWW-authenticate","Basic realm=\"请输入管理员密码\"");

                    out.print("对不起你没有权限!!");

                    return;

                }

                user=userAndPass.split(":")[0];

                pass=userAndPass.split(":")[1];

                if(user.equals("111")&&pass.equals("111")){

                    session.setAttribute("user",user);

                    RequestDispatcher dispatcher=request.getRequestDispatcher("index.jsp");

                    dispatcher.forward(request,response);

                }else{

                    response.setStatus(401);

                    response.setHeader("WWW-authenticate","Basic realm=\"请输入管理员密码\"");

                    out.print("对不起你没有权限!!");

                    return;

                }

             }catch(Exception ex){

                ex.printStackTrace();

             }

         }else{

             RequestDispatcher dispatcher=request.getRequestDispatcher("index.jsp");

             dispatcher.forward(request,response);

       }

 

 

 

 

loadrunner md5 方式一

D:\TestCase\20160126_md5\testcase_md5_generated\Actions.java

/*
 * LoadRunner Java script. (Build: _build_number_)
 * 
 * Script Description: 
 *                     
 */

import lrapi.lr;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Actions
{

	public static byte[] getKeyedDigest(byte[] buffer, byte[] key) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(buffer);
			return md5.digest(key);
		} catch (NoSuchAlgorithmException e) {
		}
		return null;
	}

	public static String getKeyedDigest(String strSrc, String key) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(strSrc.getBytes("UTF8"));
			String result = "";
			byte[] temp;
			temp = md5.digest(key.getBytes("UTF8"));
			for (int i = 0; i < temp.length; i++) {
				result += Integer.toHexString((0x000000ff & temp[i]) | 0xffffff00).substring(6);
			}
			return result;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public int init() throws Throwable {
		return 0;
	}//end of init

	public int action() throws Throwable {

		String MD5Created = null;
		String s = "000000"; //参数化数据
		// String s = lr.decrypt("56a6e6a036cd94e0011f");  
		// 若还原lr.decrypt,选中字符串鼠标右键Restore value xxxx即可。C:\Program Files\HP\LoadRunner\bin\PasswordEncoder.exe
    //MD5Created = MD5Test.getKeyedDigest(s, ""); // 左边第二个参数请填空字符串
    MD5Created = getKeyedDigest(s, "");
		System.out.println("key:" + s + ",md5:" + MD5Created); // key:000000,md5:670b14728ad9902aecba32e22fa4f6bd
		return 0;
	}//end of action

	public int end() throws Throwable {
		return 0;
	}//end of end
}

 

SSL与TLS 区别 以及介绍

http://hengstart.iteye.com/blog/840561

SSL:(Secure Socket Layer,安全套接字层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层。SSL通过互相认证、使用数字签名确保完整性、使用加密确保私密性,以实现客户端和服务器之间的安全通讯。该协议由两层组成:SSL记录协议和SSL握手协议。

TLS:(Transport Layer Security,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。该协议由两层组成:TLS记录协议和TLS握手协议。

SSL是Netscape开发的专门用户保护Web通讯的,目前版本为3.0。最新版本的TLS 1.0是IETF(工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。两者差别极小,可以理解为SSL 3.1,它是写入了RFC的。

SSL (Secure Socket Layer)

为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络

上之传输过程中不会被截取。目前一般通用之规格为40 bit之安全标准,美国则已推出128 bit之更高安全

标准,但限制出境。只要3.0版本以上之I.E.或Netscape浏览器即可支持SSL。 

当前版本为3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。

SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

SSL协议提供的服务主要有:

1)认证用户和服务器,确保数据发送到正确的客户机和服务器;

2)加密数据以防止数据中途被窃取;

3)维护数据的完整性,确保数据在传输过程中不被改变。

SSL协议的工作流程:

服务器认证阶段:1)客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接;2)服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息;3)客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器;4)服务器恢复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器。

用户认证阶段:在此之前,服务器已经通过了客户认证,这一阶段主要完成对客户的认证。经认证的服务器发送一个提问给客户,客户则返回(数字)签名后的提问和其公开密钥,从而向服务器提供认证。

从SSL 协议所提供的服务及其工作流程可以看出,SSL协议运行的基础是商家对消费者信息保密的承诺,这就有利于商家而不利于消费者。在电子商务初级阶段,由于运作电子商务的企业大多是信誉较高的大公司,因此这问题还没有充分暴露出来。但随着电子商务的发展,各中小型公司也参与进来,这样在电子支付过程中的单一认证问题就越来越突出。虽然在SSL3.0中通过数字签名和数字证书可实现浏览器和Web服务器双方的身份验证,但是SSL协议仍存在一些问题,比如,只能提供交易中客户与服务器间的双方认证,在涉及多方的电子交易中,SSL协议并不能协调各方间的安全传输和信任关系。在这种情况下,Visa和 MasterCard两大信用卡公组织制定了SET协议,为网上信用卡支付提供了全球性的标准。 

TLS:安全传输层协议 

  (TLS:Transport Layer Security Protocol) 

  安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。 TLS 记录协议提供的连接安全性具有两个基本特性:   

       私有――对称加密用以数据加密(DES 、RC4 等)。对称加密所产生的密钥对每个连接都是唯一的,且此密钥基于另一个协议(如握手协议)协商。记录协议也可以不加密使用。   

       可靠――信息传输包括使用密钥的 MAC 进行信息完整性检查。安全哈希功能( SHA、MD5 等)用于 MAC 计算。记录协议在没有 MAC 的情况下也能操作,但一般只能用于这种模式,即有另一个协议正在使用记录协议传输协商安全参数。   

       TLS 记录协议用于封装各种高层协议。作为这种封装协议之一的握手协议允许服务器与客户机在应用程序协议传输和接收其第一个数据字节前彼此之间相互认证,协商加密算法和加密密钥。 TLS 握手协议提供的连接安全具有三个基本属性:   

       可以使用非对称的,或公共密钥的密码术来认证对等方的身份。该认证是可选的,但至少需要一个结点方。 

       共享加密密钥的协商是安全的。对偷窃者来说协商加密是难以获得的。此外经过认证过的连接不能获得加密,即使是进入连接中间的攻击者也不能。 

       协商是可靠的。没有经过通信方成员的检测,任何攻击者都不能修改通信协商。 

       TLS 的最大优势就在于:TLS 是独立于应用协议。高层协议可以透明地分布在 TLS 协议上面。然而, TLS 标准并没有规定应用程序如何在 TLS 上增加安全性;它把如何启动 TLS 握手协议以及如何解释交换的认证证书的决定权留给协议的设计者和实施者来判断。 

协议结构 

  TLS 协议包括两个协议组―― TLS 记录协议和 TLS 握手协议――每组具有很多不同格式的信息。在此文件中我们只列出协议摘要并不作具体解析。具体内容可参照相关文档。

  TLS 记录协议是一种分层协议。每一层中的信息可能包含长度、描述和内容等字段。记录协议支持信息传输、将数据分段到可处理块、压缩数据、应用 MAC 、加密以及传输结果等。对接收到的数据进行解密、校验、解压缩、重组等,然后将它们传送到高层客户机。

  TLS 连接状态指的是 TLS 记录协议的操作环境。它规定了压缩算法、加密算法和 MAC 算法。

  TLS 记录层从高层接收任意大小无空块的连续数据。密钥计算:记录协议通过算法从握手协议提供的安全参数中产生密钥、 IV 和 MAC 密钥。 TLS 握手协议由三个子协议组构成,允许对等双方在记录层的安全参数上达成一致、自我认证、例示协商安全参数、互相报告出错条件。 

关系就是。。。。并列关系

最新版本的TLS(Transport Layer Security,传输层安全协议)是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。

1.TLS与SSL的差异

1)版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同,TLS的版本1.0使用的版本号为SSLv3.1。

2)报文鉴别码:SSLv3.0和TLS的MAC算法及MAC计算的范围不同。TLS使用了RFC-2104定义的HMAC算法。SSLv3.0使用了相似的算法,两者差别在于SSLv3.0中,填充字节与密钥之间采用的是连接运算,而HMAC算法采用的是异或运算。但是两者的安全程度是相同的。

3)伪随机函数:TLS使用了称为PRF的伪随机函数来将密钥扩展成数据块,是更安全的方式。

4)报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、拒绝访问(access_denied)等。

5)密文族和客户证书:SSLv3.0和TLS存在少量差别,即TLS不支持Fortezza密钥交换、加密算法和客户证书。

6)certificate_verify和finished消息:SSLv3.0和TLS在用certificate_verify和finished消息计算MD5和SHA-1散列码时,计算的输入有少许差别,但安全性相当。

7)加密计算:TLS与SSLv3.0在计算主密值(master secret)时采用的方式不同。

8)填充:用户数据加密之前需要增加的填充字节。在SSL中,填充后的数据长度要达到密文块长度的最小整数倍。而在TLS中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。

2.TLS的主要增强内容

TLS的主要目标是使SSL更安全,并使协议的规范更精确和完善。TLS 在SSL v3.0 的基础上,提供了以下增强内容:

1)更安全的MAC算法;

2)更严密的警报;

3)“灰色区域”规范的更明确的定义;

3.TLS对于安全性的改进

1)对于消息认证使用密钥散列法:TLS 使用“消息认证代码的密钥散列法”(HMAC),当记录在开放的网络(如因特网)上传送时,该代码确保记录不会被变更。SSLv3.0还提供键控消息认证,但HMAC比SSLv3.0使用的(消息认证代码)MAC 功能更安全。

2)增强的伪随机功能(PRF):PRF生成密钥数据。在TLS中,HMAC定义PRF。PRF使用两种散列算法保证其安全性。如果任一算法暴露了,只要第二种算法未暴露,则数据仍然是安全的。

3)改进的已完成消息验证:TLS和SSLv3.0都对两个端点提供已完成的消息,该消息认证交换的消息没有被变更。然而,TLS将此已完成消息基于PRF和HMAC值之上,这也比SSLv3.0更安全。

4)一致证书处理:与SSLv3.0不同,TLS试图指定必须在TLS之间实现交换的证书类型。

5)特定警报消息:TLS提供更多的特定和附加警报,以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记录。 

 

 

 

md5(32001881700052507189,32) = 71d5587077abfa5ae4843f13a98a38a3
md5(32001881700052507189,16) = 77abfa5ae4843f13

 

 

end

分享到:
评论
1 楼 javaAlpha 2010-05-26  

相关推荐

Global site tag (gtag.js) - Google Analytics