给定函数 f1 接收n个String参数,在运行时性能方面,memcache的随机密钥生成策略会被认为更好吗?
我们的Memcache客户端对它获得的密钥执行内部md5sum哈希:
public class MemcacheClient {
public Object get(String key) {
String md5 = Md5sum.md5(key)
// Talk to memcached to get the Serialization...
return memcached(md5);
}
}
我的使用场景是:
public static String f1(String s1, String s2, String s3, String s4) {
String key = s1 + s2 + s3 + s4;
return get(key);
}
/**
* Calculate hash from Strings
*
* @param objects vararg list of String's
*
* @return calculated md5sum hash
*/
public static String stringHash(Object... strings) {
if(strings == null)
throw new NullPointerException("D'oh! Can't calculate hash for null");
MD5 md5sum = new MD5();
// if(prevHash != null)
// md5sum.Update(prevHash);
for(int i = 0; i < strings.length; i++) {
if(strings[i] != null) {
md5sum.Update("_");
md5sum.Update(strings[i].toString()); // Convert to String...
md5sum.Update("_");
} else {
// If object is null, allow minimum entropy by hashing it's position
md5sum.Update("_");
md5sum.Update(i);
md5sum.Update("_");
}
}
return md5sum.asHex();
}
public static String f1(String s1, String s2, String s3, String s4) {
String key = stringHash(s1, s2, s3, s4);
return get(key);
}
请注意,第二个选项可能存在的问题是我们在已经md5sum的摘要结果上做了第二个md5sum(在memcache客户端中)。
感谢阅读, 格言。
- 编辑 使用MD5 utility source
答案 0 :(得分:1)
“更好”在什么意义上?为什么你认为第二种选择是“更好”?它做了更多的字符串连接,更多的MD5哈希,并且通常看起来效率远低于第一个......
答案 1 :(得分:1)
只是挑剔,但你可能不希望随机密钥生成,密钥生成应该是确定性,但应生成统一分发在关键领域。
如果你只考虑意外碰撞,那么第一种方法几乎没问题。您应该在字符串前面加上它们的长度,这样当子字符串从一个参数移动到另一个参数时就不会发生碰撞。鉴于md5非常好的雪崩特性,可确保意外碰撞很少被忽略。
但是如果你处理用户输入,要小心MD5,它已经知道了碰撞攻击。如果不受信任的用户可以为函数参数选择一些任意字节并返回错误的结果可能会产生安全隐患,那么您就有了安全漏洞。例如,如果您使用它来缓存授权信息,攻击者可以计算出两组散列为单个值的参数。一个人可以访问公共内容,另一个访问受保护的服务。现在只需要使用第一组请求授权,获取缓存的授权,然后使用另一组访问受保护的服务,从缓存的授权中接收绿灯。