gpt4 book ai didi

java - 使用字符串哈希码作为 etag 是否安全

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:44:37 25 4
gpt4 key购买 nike

给定一个特定的输入参数,对于 rest api,我想使用哈希码作为 etag。json 响应发生变化且 hashcode 相同的概率是多少?

或者有更好的方法吗?

@GET
public Response getConfigurationForView(@PathParam("in1") String in1, @Context Request request) throws Exception {
String jsonResponse = getJsonResponse(in1);
EntityTag etag = new EntityTag(Integer.toString(in1.hashCode()) + "-" + Integer.toString(jsonResponse.hashCode()));
ResponseBuilder builder = request.evaluatePreconditions(etag);


if(builder == null){
builder = Response.ok(jsonResponse, MediaType.APPLICATION_JSON);
builder.tag(etag);
}

return builder.build();
}

最佳答案

鉴于您只有 40 亿种可能的哈希码用于各种字符串,因此您最终会遇到 ETag 冲突的可能性很大。

看看 String.hashCode() 是如何实现的:

        char val[] = value;

for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;

-- 您甚至可以自己想出可能发生的碰撞。例如,""(空字符串)和 "\0"(仅包含 \0 字符的字符串)会给您相同的结果hashCode 为 0。

我建议您使用 SHA1 哈希(或 MD5,但请先参阅 securityCPU running time 上的这些说明)。

假设您继续使用 SHA1 哈希,您的代码可能如下所示:

public static String calculateEtag(final String s) throws java.security.NoSuchAlgorithmException {
final java.nio.ByteBuffer buf = java.nio.charset.StandardCharsets.UTF_8.encode(s);
final java.security.MessageDigest digest = java.security.MessageDigest.getInstance("SHA1");
buf.mark();
digest.update(buf);
buf.reset();
return String.format("W/\"%s\"", javax.xml.bind.DatatypeConverter.printHexBinary(digest.digest()));
}

这将产生与 sha1sum 实用程序相同的输出。您也可以使用 BigInteger 将字节缓冲区转换为十六进制字符串:

new BigInteger(1, digest.digest()).toString(16)

-- 但是 javax.xml.bind.DatatypeConverter.printHexBinary() 快了几倍。

关于java - 使用字符串哈希码作为 etag 是否安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28959576/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com