【发布时间】:2011-03-30 11:55:20
【问题描述】:
我有一个 Android 应用程序,它是客户端/服务器设计中的“服务器”。在应用程序中,我需要针对一组字符串计算 MD5 哈希并将结果返回给客户端,以便让它们之间的对话继续进行。我的代码是从那里的众多示例中拼凑而成的。计算哈希的算法(不是我设计的)是这样的:
- 将字符串转换为字节数组
- 使用 MessageDigest 类生成哈希
- 将生成的哈希转换回字符串
对于 99% 的客户来说,哈希似乎是正确的。一位看到错误哈希的客户正在使用德语语言环境运行,这让我开始怀疑语言是否会影响我得到的结果。这是从字符串中生成字节数组的代码:
public static byte[] hexStringToByteArray(String s)
{
byte[] data = null;
if(s.length() % 2 != 0)
{
s = "0" + s;
}
int len = s.length();
data = new byte[len / 2];
for (int i = 0; i < len; i += 2)
{
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
这是哈希函数的当前版本:
public static String hashDataAsString(String dataToHash)
{
MessageDigest messageDigest;
try
{
messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
byte[] data = hexStringToByteArray(dataToHash);
messageDigest.update(data);
final byte[] resultByte = messageDigest.digest();
return new String(Hex.encodeHex(resultByte));
}
catch(NoSuchAlgorithmException e)
{
throw new RuntimeException("Failed to hash data values", e);
}
}
我正在使用Hex.encodeHex function from Apache Commons。
我已尝试将手机切换到德语区域设置,但我的单元测试仍会产生正确的哈希结果。该客户使用的是库存 Froyo,因此消除了自定义 ROM 出现故障的风险。我还找到了将字节转换为字符串的替代方法:
public static String MD5_Hash(String s) {
MessageDigest m = null;
try {
m = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//m.update(s.getBytes(),0,s.length());
byte [] data = hexStringToByteArray(s);
m.update(data, 0, data.length);
String hash = new BigInteger(1, m.digest()).toString(16);
return hash;
}
在我的单元测试中,结果相同。在这里使用 BigInteger 是否更安全?
【问题讨论】: