第一次写博客,写的不好的地方请见谅,决定开始写博客主要是想记录下每天所学的东西,同时也希望有可能的话给像我一样的初学者的朋友一点帮助,因为我也是初学者,遇到的很多问题可能某些朋友也会遇到,不多说了,开始写了。
今天开发中遇到个小问题,就是.netMD5加密后的结果与Java加密后的结果不一样,于是百度和google了很久,没找到什么好的解决方法,搜到的大多是因为中文字符加密的不同,此处这个我就不多说了,网上有很多朋友介绍了,主要就是编码方式的不一样,其实像涉及到中文字符的地方,如果出问题了,第一个要查的问题就是编码方式。
下面说说我今天遇到的问题,我方程序(.net)中用MD5加密的结果与对方程序(java)中加密的结果不一样,最后实在是查补出来什么,让对方将java的加密代码发了过来,花了两个多小时的时间,总算是解决了(说来可笑,最后还是微软的哥哥搞定的,这里拿出来分享下,多的东西部说了,直接贴代码了)。
首先来看下.net中,MD5是如何加密的,具体代码如下:
/** <summary>
/// MD5 16位加密
/// </summary>
/// <param name="ConvertString"></param>
/// <returns></returns>
public static string GetMd5Str16(string ConvertString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
t2 = t2.Replace("-", "");
return t2;
}
/** <summary>
/// MD5 32位加密
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string GetMd5Str32(string str)
{
string cl = str;
StringBuilder pwd = new StringBuilder(256);
MD5 md5 = MD5.Create();//实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
//byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
byte[] s = md5.ComputeHash(Encoding.Unicode.GetBytes(cl));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 0; i < s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
pwd.Append(s[i].ToString("X").PadLeft(2,'0'));
}
return pwd.ToString();
}
JAVA中的加密代码:
public static String getMD5String(String str)
{
try
{
byte[] res=str.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5".toUpperCase());
//下面这句是非常重要的,不知道JAVA的这个MD5算法为什么要加上这句,如果去掉这一句
//加密出来的结果和上面GetMd5Str32 方法,也就是.NET提供的MD5加密的结果是一样的
//加上这句话后加密出来的结果就不一样了,其实这句话的效果和下面加粗字体的语句效果
//一样,从JAVA API文档中发现 使用指定的 byte 数组对摘要进行最后更新,然后完成摘要计算。也就是说,此方法首先调用 update(input),向 update 方法传递 input 数组,然后调用 digest()。
//byte[] result=md.digest(res);
[b]
for(int i=0;i<result.length;i++)
{
md.update(result[i]);
}
byte[] hash=md.digest();
[/b]
StringBuffer d=new StringBuffer("");
for(int i=0;i<hash.length;i++)
{
int v=hash[i] & 0xFF;
if(v<16) d.append("0");
d.append(Integer.toString(v,16).toUpperCase()+"");
}
return d.toString();
}
catch(Exception e)
{
return "";
}
}
以上JAVA代码中注释了很多的那句话,如果加上的话,该怎么处理呢,卖个关子,呵呵...
有需要的朋友M我(binwu95042$mail.com($换成@)) 或者加我Q
今天开发中遇到个小问题,就是.netMD5加密后的结果与Java加密后的结果不一样,于是百度和google了很久,没找到什么好的解决方法,搜到的大多是因为中文字符加密的不同,此处这个我就不多说了,网上有很多朋友介绍了,主要就是编码方式的不一样,其实像涉及到中文字符的地方,如果出问题了,第一个要查的问题就是编码方式。
下面说说我今天遇到的问题,我方程序(.net)中用MD5加密的结果与对方程序(java)中加密的结果不一样,最后实在是查补出来什么,让对方将java的加密代码发了过来,花了两个多小时的时间,总算是解决了(说来可笑,最后还是微软的哥哥搞定的,这里拿出来分享下,多的东西部说了,直接贴代码了)。
首先来看下.net中,MD5是如何加密的,具体代码如下:
/** <summary>
/// MD5 16位加密
/// </summary>
/// <param name="ConvertString"></param>
/// <returns></returns>
public static string GetMd5Str16(string ConvertString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
t2 = t2.Replace("-", "");
return t2;
}
/** <summary>
/// MD5 32位加密
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string GetMd5Str32(string str)
{
string cl = str;
StringBuilder pwd = new StringBuilder(256);
MD5 md5 = MD5.Create();//实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
//byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
byte[] s = md5.ComputeHash(Encoding.Unicode.GetBytes(cl));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 0; i < s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
pwd.Append(s[i].ToString("X").PadLeft(2,'0'));
}
return pwd.ToString();
}
JAVA中的加密代码:
public static String getMD5String(String str)
{
try
{
byte[] res=str.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5".toUpperCase());
//下面这句是非常重要的,不知道JAVA的这个MD5算法为什么要加上这句,如果去掉这一句
//加密出来的结果和上面GetMd5Str32 方法,也就是.NET提供的MD5加密的结果是一样的
//加上这句话后加密出来的结果就不一样了,其实这句话的效果和下面加粗字体的语句效果
//一样,从JAVA API文档中发现 使用指定的 byte 数组对摘要进行最后更新,然后完成摘要计算。也就是说,此方法首先调用 update(input),向 update 方法传递 input 数组,然后调用 digest()。
//byte[] result=md.digest(res);
[b]
for(int i=0;i<result.length;i++)
{
md.update(result[i]);
}
byte[] hash=md.digest();
[/b]
StringBuffer d=new StringBuffer("");
for(int i=0;i<hash.length;i++)
{
int v=hash[i] & 0xFF;
if(v<16) d.append("0");
d.append(Integer.toString(v,16).toUpperCase()+"");
}
return d.toString();
}
catch(Exception e)
{
return "";
}
}
以上JAVA代码中注释了很多的那句话,如果加上的话,该怎么处理呢,卖个关子,呵呵...
有需要的朋友M我(binwu95042$mail.com($换成@)) 或者加我Q