2009-08-06 157 views
4

我目前正在尝试修改现有的GWT-Ext应用程序,即在MySql数据库中使用纯文本密码。在GWT/GWT-Ext中密码字符串的md5散列?

我的计划是使用md5哈希函数,因为现有的密码可以很容易地通过MySql函数进行修改,而且我期待为GWT-Ext端找到一个简单的解决方案。但正如我发现的那样,GWT不支持java.security,并且似乎没有任何其他实现可用于将密码字符串更改为客户端上的md5散列。

只有“解决方案”我发现至今,是重新实现通过JSNI一个MD5方法如下所述: http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/ad09475a9944c9f8

没有为EXT-JS的现有用户扩展,但我无法找到任何GWT-Ext: http://extjs.com/forum/showthread.php?p=133516

有没有人知道更优雅/简单的方法来解决这个问题?也许我应该使用别的东西而不是md5来确保密码被加密?

干杯 弗兰克

回答

9

就个人而言,我会说你这样做是错误的。我不会在客户端散列密码(这是GWT的)。如果你把你的密码拼凑在一起,你无疑会想要用它来欺骗它,否则你将很容易受到rainbow攻击。如果你在客户端散列+盐,你的用户可以访问你的salt。

如果我是你,我会在服务器端散列+ salt密码。这将允许您使用标准的Java代码来执行MD5哈希。

我的2美分。

-jP

+0

如果他在客户端执行类似cram-md5的事情,客户端计算hmac(md5哈希加上一个随机数salt)并将其发送到服务器,那么这不是一个错误的方案。缺点是服务器需要明文密码才能检查hmac。 – 2009-08-06 18:59:02

+0

关于彩虹攻击的好处,以前不知道。我也通过在服务器端进行加密来解决这个问题,但是我的想法是,在将密码发送到服务器之前,我想加密密码,因为我们目前只使用http而没有https。 – FrankS 2009-08-06 21:27:57

+0

GWT是客户端和服务器端。除此之外,这个职位是很好的建议。不要在客户端散列它。看看http://www.owasp.org/index.php/Hashing_Java。 – 2009-09-01 12:33:05

6

,可能适合你需要的是一些所谓的零知识权威性另一个想法。 (即服务器永远不需要知道用户的明文密码)

基本上,在设置初始密码时,客户端将用户密码哈希N次(其中N是1000的较大数字),然后发送服务器存储散列和N.

稍后,当用户想要认证时,服务器告诉客户端N-1,并且客户端清除了用户键入的密码N -1次并发送到服务器。服务器对收到的散列做了1次散列,并且(希望)得到存储的散列。服务器然后存储N-1哈希和N-1号码。

每次用户认证,服务器递减存储的N并保存以前的散列值。

当N下降到0时,用户必须选择并设置一个新密码。

服务器必须确保它从不要求相同的迭代,否则它很容易重播。你不能真正从客户端执行这个条件,因为客户端(尤其是浏览器)不能可靠地跟踪最后一个N.

+0

非常有趣的想法,并没有想过之前。目前的解决方案并不适合,但我会牢记以备将来参考,谢谢:-) – FrankS 2009-08-07 07:59:20

+1

有趣的想法让我花了一些时间思考它,但它很容易受到中间人攻击。 在认证请求上,服务器发送一些数字M.攻击者发送(M-1)到客户端,并接收到散列(M-1)。攻击者尝试再次进行身份验证,从服务器接收挑战(M-1),并使用散列(M-1)进行响应。攻击者现在被认证。 – rix0rrr 2010-01-06 11:14:44

+0

是的,这听起来像一个问题。我首先想到的是要求服务器在向客户端挑战期间发布它时不重用M。然而,更大的问题仍然是Mallory可以告诉客户端M-100,从客户端收集哈希(M-100),然后用截获的哈希登录多达100次。我将不得不去看看我第一次遇到这个项目是否找到了相同的问题并处理了它,或者放弃了零知识验证。 – 2010-01-06 16:57:40

2

您可以使用gwt-crypto使用生成的客户端SHA-1哈希:

String getSHA1for(String text) { 
    SHA1Digest sd = new SHA1Digest(); 
    byte[] bs = text.getBytes(); 
    sd.update(bs, 0, bs.length); 
    byte[] result = new byte[20]; 
    sd.doFinal(result, 0); 
    return byteArrayToHexString(result); 
} 

String byteArrayToHexString(final byte[] b) { 
    final StringBuffer sb = new StringBuffer(b.length * 2); 
    for (int i = 0, len = b.length; i < len; i++) { 
    int v = b[i] & 0xff; 
    if (v < 16) sb.append('0'); 
    sb.append(Integer.toHexString(v)); 
    } 
    return sb.toString(); 
}