我有一个 C# WebService 和一个 (Java) Android 应用程序。是否有一个 SIMPLE 哈希函数可以在这两种语言之间产生相同的结果?最简单的 C# 哈希是 String.GetHashCode(),但我无法在 Java 中复制它。最简单的 Java 散列一点也不简单。而且我不知道我是否可以在 C# 中完全复制它。
如果相关,我会在通过互联网发送密码之前对密码进行哈希处理。我目前正在使用 Encode64,但这显然不安全,因为我们可以反转它。
编辑:好的,我决定使用 SHA256。如果其他人需要快速解决方案,这里是我使用的代码,考虑到我希望 C# 和 Java 都输出完全相同的字符串并且我需要尽可能简单的解决方案。
Java
public String Hash(String s)
{
StringBuffer sb = new StringBuffer();
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(s.getBytes());
byte byteData[] = md.digest();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16)
.substring(1));
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return sb.toString();
}
C#
public static string Hash(String s)
{
HashAlgorithm Hasher = new SHA256CryptoServiceProvider();
byte[] strBytes = Encoding.UTF8.GetBytes(s);
byte[] strHash = Hasher.ComputeHash(strBytes);
return BitConverter.ToString(strHash).Replace("-","").ToLowerInvariant().Trim();
}
谢谢大家! :)
最佳答案
首先,由 String.GetHashCode()
和 String.hashCode()
实现的哈希类型并非设计用于此类事情。首先,它们仅散列为 32 但数字(至少在 Java 的情况下),因此存在很大的冲突风险。在这种情况下,如果两个不同的密码映射到相同的哈希值……那么某人有 2^32 分之一的机会接受随机选择的密码。 (另一方面,如果坏人可以拦截有效密码的 32 位散列,他们在猜测原始密码是什么方面就有很大的“优势”!)
其次,发送加密散列(例如由 MD5、SHA-256 等生成)可能无法解决您的安全问题……除非您通过 SSL 或其他方式发送散列。当然,坏人将无法恢复原始密码,但他们可以拦截并在“重放”攻击中使用哈希。 (有一些方法可以解决这个问题,但它们要么需要共享 key ,要么使用公钥/私钥加密......如果你想确保安全,你必须知道你在做什么。)
简而言之,您需要与具有扎实的安全专业知识的人讨论您的整个问题和建议的解决方案。
如果您真的认为这不是安全问题,那么 MD5 散列应该没问题。但是不要说你没有被警告过......
(但不要使用简单的 32 位哈希码,因为它仅比 base64 更安全。)
关于c# - C# 和 Java 之间始终相等的简单哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10859704/