我有一个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();
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
多谢你们!:)
首先,通过那种实现哈希String.GetHashCode()和String.hashCode()用于这种东西不是设计.首先,它们只散列到32但是数字(至少在Java情况下),因此存在很大的冲突风险.在这种情况下,如果两个不同的密码映射到相同的散列...那么某人有机会在2 ^ 32中接受随机选择的密码.(另一方面,如果坏人可以拦截有效密码的32位哈希,他们在猜测原始密码是什么时有一个很大的"支持"!)
其次,发送加密哈希(例如由MD5,SHA-256等产生)可能不会解决您的安全问题......除非您通过SSL或其他东西发送哈希.当然,坏人将无法恢复原来的密码,但他们可以拦截并在"重播"攻击中使用哈希.(有很多方法可以解决这个问题,但它们要么需要共享密钥,要么使用公钥/私钥加密......如果您希望这样做是安全的,您必须知道自己在做什么.)
简而言之,您需要与具有扎实安全专业知识的人讨论您的整个问题和建议的解决方案.
如果你真的认为这不是一个安全问题,那么MD5哈希应该没问题.但是不要说你没有被警告......
(但是不要使用简单的32位哈希码,因为它几乎比base64更安全.)