存档二月, 2006

RSS相关的工具

RSS的读取与创建目前我已经找到的Java方面的第三方库有:

  1. RSSLib4J:http://rsslib4j.sourceforge.net/
  2. RSS Utilities:可以找到一篇教程:http://java.sun.com/developer/technicalArticles/javaserverpages/rss_utilities/
  3. ROME: RSS and Atom Utilities for Java
    https://rome.dev.java.net/

经过选择,我觉得在我的项目中采用ROME。

具体怎么使用,比如怎么读取RSS Feed和创建RSS Feed,我还在学习中,ROME的WIKI提供了教程:http://wiki.java.net/bin/view/Javawsxml/Rome05Tutorials

留言

开源的基于JavaScript的HTML编辑器

TinyMCE,也就是现在这个Blog所用的文本编辑器,是一个基于LGPL的开源项目,其网址是:http://tinymce.moxiecode.com/

下载下来之后,其使用非常简单:

这样当前页面中的所有的textarea都自动变成HTML编辑器了。

留言

JSPWiki

如果想自己建个Wiki的话,用JSPWiki就不错,网址是:http://www.jspwiki.org/

还可以找一些模板来用,http://www.jspwiki.org/Wiki.jsp?page=ContributedTemplates

比如我用的模板:http://www.smallpiece.info:8080/wiki/Wiki.jsp?page=SmallpieceTemplate

就很不错的。

 

留言

Venkman for Firefox 1.5

很好用的JavaScript调试器,写Ajax程序不错的帮手。

下载地址:http://getahead.ltd.uk/ajax/venkman

直接安装就可以了。

留言

Struts-menu配置菜单外观

用了Struts-menu,菜单默认的外观自然不能令人满意。于是需要自己定义菜单的外观。

可以从jar包net.sf.navigator.displayer目录下面找到DisplayerStrings.properties文件,拷贝出来并放到WEB-INF/classes下面,里面定义了很多的属性值,基本上从属性的名字就可以猜出来其作用,比如dd.menu.top就是DropDown风格菜单的顶部的HTML代码。属性具体的使用方式,可以看Displayer的源文件。

接下来的工作就是替换属性文件里面的属性了,换成你想要的HTML代码。然后在useMenuDisplayer这个tag中指定config属性为你的配置文件就可以了。比如你的配置文件名字是WEB-INF/classes/DisplayerString.properties, 则写成<menu:useMenuDisplayer name=”DropDown” bundle=”SampleMenu” config=”DisplayerString” >。其中的bundle用来指定i18n的properties文件。

 

评论(1)

Struts-menu还不错,挺好用的

网站需要一个导航菜单,发现Struts-menu挺不错,网址:http://struts-menu.sourceforge.net/

下载下来之后,也很好用。首先加入Maven2的repository。我用的是Spring,直接在web.xml里面添加一个listener,然后在Spring的XML文件中添加一个Bean的定义即可。

然后就是把下载下来的包里面附带的例子里面的menu-config.xml修改修改,放到自己的WEB-INF目录下面,再写一个类似的JSP页面就OK了。它还支持从数据库中读取数据来动态生成菜单,完全满足了我的需求,而且够简单,够实用。

 

留言

Ajax Rss Reader

嗯,想做一个这样的东西。

Google了一下,找到了一个:http://www.creotec.com/rss_ajax/;试用了一下,添加了一个新浪体育新闻的RSS地址,感觉不错。

晚上研究改造一下,^_^。

留言

基于Challenge-Response的登录系统的简单实现

根据我翻译的那篇文章:Login System(登录系统)的思想,我简单实现了一下基于Challenge-Response的登录系统。

实现:JavaScript

所用库:x libmd5.js

JavaScript的源代码如下(ChallengeResponseLogin.js):

function ChallengeResponseLogin(formId, inputUserNameId, inputPasswordId, btnSubmitId, hiddenChallengeId) {
 if (typeof(formId) != “string”
  || typeof(inputUserNameId) != “string”
  || typeof(inputPasswordId) != “string”
  || typeof(btnSubmitId) != “string”
  || typeof(hiddenChallengeId) != “string”)
 {
  //Illegal arguments type.
  return;
 }
 
 this.form = xGetElementById(formId);
 this.inputUsername = xGetElementById(inputUserNameId);
 this.inputPassword = xGetElementById(inputPasswordId);
 this.btnSubmit = xGetElementById(btnSubmitId);
 this.hiddenChallenge = xGetElementById(hiddenChallengeId);
 this.systemSalt = “SystemSalt”;
 
 if (this.form && this.inputUsername && this.inputPassword
  && this.btnSubmit && this.hiddenChallenge)
 {
  this.btnSubmit.onclick = this.doLogin;
  this.btnSubmit.crLogin = this;
 }
}

ChallengeResponseLogin.prototype = {
 doLogin : function(event) {
  var e = new xEvent(event);
  if (e.target && e.target.crLogin)
  {
   var login = e.target.crLogin;
   var username = login.inputUsername.value;
   var password = login.inputPassword.value;
   var challenge = login.hiddenChallenge.value;
   if (username == “” || password == “” || challenge == “”)
   {
    return;
   }
   var salt = username + login.systemSalt;
   var hmac_pwd_salt = hex_hmac_md5(password, salt);
   var cryptedPassword = hex_hmac_md5(hmac_pwd_salt, challenge);
   login.inputPassword.value = cryptedPassword;
   login.form.submit();
  }
 }
}

使用:

function createCRLogin() {
 var crLogin = new ChallengeResponseLogin(”loginForm”, “inputUsername”,”inputPassword”,”btnSubmit”,”challenge”);
}

参数的意义依次是:登录表单ID,用户名输入框ID,密码输入框ID,提交按钮ID,存放Challenge值的隐藏域ID。

说明:

  • 这个程序非常简单,只是在提交之前用加密后的值替换密码输入框的值而已。
  • 我本来想加入Ajax功能,但是考虑到我后台是用Acegi Security的,该框架封装了很多东西,即服务器端如果要完全控制的话,就很麻烦。所以我放弃了。

 

留言

Login System(登录系统)

翻译自:http://pajhome.org.uk/crypt/md5/auth.html

Challenge Response
登录系统的核心是“challenge response”的交换。服务器生成一个随机数(“challenge”)并发送到客户端。客户端根据challenge和密码进行hash操作,并把结果发送回服务器。服务器根据自己的计算检查结果。在交换过程中,密码不作为明文传送。由于每次的challenge不同,避免了重放攻击。

登录表单由两个部分组成:

1.由服务器生成的是16进制表示的128位随机数,存放在名为“challenge”的隐藏域中。

2.在onsubmit代码中:password.value = hex_hmac_md5(password.value, challenge.value)

当服务器收到表单数据后,使用其保存的密码来计算hex_hmac_md5(password, challenge),并与客户端传送过来的进行比较,如果一致则登录成功。

很重要的一点是服务器必须记录它生成的challenges,并只接受那些用来登录的challenges。当一个challenge被用于登录后,它必须设成无效。实际的系统需要一个机制来周期性的使得生成但是没有使用的challenges过期。

 

Tracking the Login Session
一旦登录发生,服务器必须跟踪用户的session。推荐使用cookie中的session ID。如果这样的话,session cookie可以被嗅探到并重放。然而这样的影响比使用密码要小得多,因为session ID是时间受限的。理论上可以通过对会话中的每一次请求使用challenge-response来避免这个问题,然而太复杂以至于无法正常的编码实现。所以可以接收被嗅探到的风险;如果不能接收的话,可以使用HTTPS。

 

Transferring the Password Initially
基于challenge response的登录假定服务器已经知道密码。因为当传送最初的密码时,需要使用其它的方法。可以通过JavaScript RSA来实现,推荐使用512位的密钥。

 

Protecting the Password on the Server
在服务器保存明文的密码是有很大风险的,考虑如果数据库被攻破的情况。因为用户通常在不同的系统之间重用密码,攻击者可以使用密码去访问其它的系统。很多企业的密码策略禁止保存明文密码。

通常的解决办法是password hashing。例如,Unix的密码文件通常使用基于MD5的算法来加密密码。该算法包含一个称为“salt”的数字,该数字对每个用户都是随机生成的。“salt”并不是保密的。它的作用是同样的密码可以加密成不同的hashes。

这种方法可以应用到基于challenge response的登录系统。

1.  服务器发送(challenge, salt)

2.  客户端发送hex_hmac_md5(hex_hmac_md5(password, salt), challenge)

使用这种方法,服务器保存salt和hex_hmac_md5(password, salt),并不保存明文的密码。实际上服务器保存的是“password equivalent”的,即你知道这些值的话,就可以登录。不过,这样的保护是值得的,因为它的主要目的是防止攻击者在其它系统上使用其捕获的密码。

 

对每个用户使用不同的salt带来一个问题:当用户名未知时salt也是未知的。对于一个web应用程序来说,这需要一个两阶段的登录表单,一个表单用来获取用户名,另外一个用来获取密码。这样的方式对用户是相当不友好的。一个简单的解决办法是:salt是由用户名和一个system salt连接而成的。system salt对所有用户都是一样的。

 

Brute Force Attacks
暴力攻击是指攻击者对一个用户使用不同的密码,直到最终成功。使用基于challenge-respons的登录方式带来一个新的风险。如果攻击者捕获了登录会话,他们就可以进行离线的暴力破解,不需要访问服务器就能检查密码。这样就避开了很多服务器的限制,比如3次不正确输入密码就锁住账号。

主要的解决办法就是使用强密码。如果用户使用长的随机密码,则暴力破解需要更多的计算能力。另外一个增加攻击者计算能力的方法就是重复使用MD5操作,攻击者就需要对每个密码重复同样的事情。

 

In Case JavaScript is Disabled
JavaScript不是总启用的。这种情况下,加密的登录是不可能的。有两种选择:要么阻止登录,要么以不加密的方式继续。这是一个安全性和可用性的tradeoff。不同的站点有不同的选择。

为了允许不加密的登录,需要对登录表单进行修改。增加一个password_hash的隐藏域,用JavaScript来填写其值,并使得密码域为空。如果服务器收到一个为空的password_hash,则说明JavaScript被禁用了,服务器可以检查密码域。

阻止不加密的登录有点难度。可以用JavaScript来生成登录表单的HTML,如果JavaScript被禁用的话,该表单不出现。另外一种方式是把表单的target设成about:blank,然后在JavaScript OnSubmit中设置。

留言

Ajax Security (3) - Ajax的问题

以下内容参考自:http://www.it-observer.com/articles/1062/ajax_security/

Ajax安全的大多数问题来自于服务器端的有缺陷的实现。使用安全coding技术的良好设计会使得Ajax更加安全。
其他问题:

  • 新的技术:Ajax毕竟是一些新技术,在网上能找到的好的例子较少。
  • 非传统的设计:Ajax包括客户端和服务器两个部分,需要不同的技术。
  • 太多的脚本:Ajax导致过多的脚本以及与此对应的服务器页面。
  • 为了Ajax而Ajax的想法:这种想法是不正确的,Ajax会带来很多很cool的效果,但是与之而来的是相应的测试。
  • 不安全的通讯:Ajax调用传输的数据可能很小,但是这些数据可能是隐私和保密的。
  • 服务器端的访问控制:使用JavaScript过程来调用Ajax可能会掩盖明显的编程错误。
  • 服务器端验证:很重要。
  • 客户端验证:如果客户端是执行服务器返回的JavaScript代码的话,验证也是必须的。

Ajax安全提示:
为了成功,需要从一个好的计划开始。集中精力来降低和简化Ajax调用,为响应创建标准的格式(一般是XML)。

  • 遵循最佳实践。尤其包括检查访问控制和输入验证的缺陷;保证敏感数据通过SSL传输。
  • 不要认为服务器端的Ajax对访问控制和用户输入的验证可以取代服务器上的检查。使用Ajax不会减少验证的工作量,反而会加大。
  • 不要认为客户端的混淆可以包含你最重要的商业秘密。使用JavaScript是隐藏编程技巧和领先竞争者的很差的方式。
  • 最后,对你的开发团队进行严格的控制。使用Ajax可以达到很棒的效果,但是可以考虑把它们移到第二版再说,首先集中精力构建稳定的第一版。

网站开发最佳实践的参考网站:

Open Web Application Security Project (OWASP)

http://www.owasp.org/

留言

« Previous entries