翼度科技»论坛 编程开发 .net 查看内容

C#.NET与JAVA互通之MD5哈希V2024

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
C#.NET与JAVA互通之MD5哈希V2024
 
配套视频:
 
 
要点:
1.计算MD5时,SDK自带的计算哈希(ComputeHash)方法,输入输出参数都是byte数组。就涉及到字符串转byte数组转换时,编码选择的问题。
2.输入参数,字符串转byte数组时,编码双方要统一,一般为:UTF-8。
3.输出参数,byte数组转字符串时,编码双方要统一,一般为:16进制字符串(注意大小写);也有人选择BASE64字符串。
4.如果你的MD5用于存储密码,最好要加盐。
5.MD5用于签名,常见的运算过程。
 
开整:
一、.NET 算MD5
1.常用.NET MD5 代码:
  1. string orgKey = "HelloWorld";
  2. Console.WriteLine("待哈希字符串:" + orgKey);
  3. MD5 md = MD5.Create();
  4. byte[] bytes = Encoding.UTF8.GetBytes(orgKey);
  5. byte[] buffer2 = md.ComputeHash(bytes);
  6. string str = "";
  7. for (int i = 0; i < buffer2.Length; i++)
  8. {
  9.     str = str + buffer2[i].ToString("x2");
  10. }
  11. Console.WriteLine("哈希后转16进制小写:" + str);
复制代码
输出效果(小写x):
  1. 待哈希字符串:HelloWorld
  2. 哈希后转16进制小写:68e109f0f40ca72a15e05cc22786f8e6
复制代码
注意:.ToString("x2") 里面的x是小写,即输出16进制小写。

 
 如果X是大写,则输出16进制大写字符串。代码如下:
  1. str = "";
  2. for (int i = 0; i < buffer2.Length; i++)
  3. {
  4.     str = str + buffer2[i].ToString("X2");
  5. }
  6. Console.WriteLine("哈希后转16进制大写:" + str);
复制代码
输出效果(大写X):
  1. 待哈希字符串:HelloWorld
  2. 哈希后转16进制大写:68E109F0F40CA72A15E05CC22786F8E6
复制代码
 
如果不使用.ToString("x2") ,我们还可以使用BitConverter来转换为16进制字符串。
但BitConverter默认转出的字符串是大写并带“-”符号。代码如下:
  1. string orgKey = "HelloWorld";
  2. Console.WriteLine("待哈希字符串:" + orgKey);
  3. MD5 md = MD5.Create();
  4. byte[] bytes = Encoding.UTF8.GetBytes(orgKey);
  5. byte[] buffer2 = md.ComputeHash(bytes);
  6. string str = "";
  7. str = BitConverter.ToString(buffer2);
  8. Console.WriteLine("哈希后用BitConverter转16进制原始:" + str);
复制代码
BitConverter.ToString 默认输出效果:
  1. 待哈希字符串:HelloWorld
  2. 哈希后用BitConverter转16进制原始:68-E1-09-F0-F4-0C-A7-2A-15-E0-5C-C2-27-86-F8-E6
  3. 结束 。
复制代码
我们BitConverter.ToString转小写,并不带“-”符号。代码如下:
  1. string orgKey = "HelloWorld";
  2. Console.WriteLine("待哈希字符串:" + orgKey);
  3. MD5 md = MD5.Create();
  4. byte[] bytes = Encoding.UTF8.GetBytes(orgKey);
  5. byte[] buffer2 = md.ComputeHash(bytes);
  6. string str = "";
  7. str = BitConverter.ToString(buffer2).Replace("-", "").ToLower();
  8. Console.WriteLine("哈希后用BitConverter转16进制小写:" + str);
复制代码
效果:
  1. 待哈希字符串:HelloWorld
  2. 哈希后用BitConverter转16进制小写:68e109f0f40ca72a15e05cc22786f8e6
  3. 结束 。
复制代码
 
 
二、JAVA MD5
JAVA 算MD5代码:
 
  1. public static void main( String[] args )
  2.     {
  3.         try
  4.         {
  5.             String input = "HelloWorld";
  6.             String md5Hash = getMD5Hash(input);
  7.             System.out.println("待哈希字符串 '" + input + "' 16进制小写: " + md5Hash);
  8.         }catch (Exception ex){
  9.             System.out.println( "ex!"+ex.getMessage() );
  10.         }
  11.         System.out.println( "结束!" );
  12.     }
  13.     public static String getMD5Hash(String input) {
  14.         try {
  15.             byte[] byInput=input.getBytes();//默认是UTF-8
  16.             // 获取MD5 MessageDigest实例
  17.             MessageDigest md = MessageDigest.getInstance("MD5");
  18.             // 更新要计算哈希的输入
  19.             md.update(byInput);
  20.             // 完成哈希计算并返回
  21.             byte[] digest = md.digest();
  22.             // 将字节数组转换为16进制的字符串
  23.             StringBuilder sb = new StringBuilder();
  24.             for (byte b : digest) {
  25.                 sb.append(String.format("%02x", b & 0xff));
  26.             }
  27.             // 转换为小写(如果需要)
  28.             return sb.toString().toLowerCase();
  29.         } catch (NoSuchAlgorithmException e) {
  30.             throw new RuntimeException("MD5 not supported", e);
  31.         }
  32.     }
复制代码
 
 
输出效果:
  1. 待哈希字符串 'HelloWorld' 16进制小写: 68e109f0f40ca72a15e05cc22786f8e6
  2. 结束!
复制代码

 
 
三、同一个字符串 .NET MD5 与 JAVA 是否一致
双方待哈希字符串都为“HelloWorld”,且转16进制小写。将.NET算得的结果,放到JAVA中进行比较:
  1. String input = "HelloWorld";
  2.             String javaMd5Hash = getMD5Hash(input);
  3.             System.out.println("JAVA算出的MD5值:" + javaMd5Hash  );
  4.             String netStr="68e109f0f40ca72a15e05cc22786f8e6";
  5.             System.out.println(".NET算出的MD5值:" + netStr  );
  6.             boolean bPP=netStr.equals(javaMd5Hash);
  7.             System.out.println("两者是否匹配:" + bPP  );
复制代码
效果:
  1. JAVA算出的MD5值:68e109f0f40ca72a15e05cc22786f8e6
  2. .NET算出的MD5值:68e109f0f40ca72a15e05cc22786f8e6
  3. 两者是否匹配:true
  4. 结束!
复制代码
 
 
四、MD5加盐
假设你的登录名为:HelloWorld,密码是:123456,密码用MD5 HASH后存储,未加盐,数据库被脱库,对方得到了HelloWorld对应的密码存储MD5值:e10adc3949ba59abbe56e057f20f883e。
对方就可以用撞库,即:计算从 100000 到 999999 之间的MD5 HASH值,每次算出MD5值后,与e10adc3949ba59abbe56e057f20f883e比对,如果相等,则反推出HelloWorld的密码。
代码模拟:
  1. static void Main(string[] args)
  2. {
  3.     try
  4.     {
  5.         string targetMd5 = "e10adc3949ba59abbe56e057f20f883e";
  6.         Console.WriteLine("目标MD5 值:" + targetMd5);
  7.         for (int i = 100000; i <= 999999; i++)
  8.         {
  9.             string tmpMd5 = GetMd5(i.ToString());
  10.             if (tmpMd5 == targetMd5) {
  11.                 Console.WriteLine("MD5 已匹配,对应密码:" + i.ToString());
  12.                 break;
  13.             }
  14.         }
  15.     }
  16.     catch (Exception ex)
  17.     {
  18.         Console.WriteLine("ex:"+ex.Message);
  19.     }
  20.     Console.WriteLine("结束 。"  );
  21.     Console.ReadKey();
  22. }
  23. static string GetMd5(string orgKey) {            
  24.     MD5 md = MD5.Create();
  25.     byte[] bytes = Encoding.UTF8.GetBytes(orgKey);
  26.     byte[] buffer2 = md.ComputeHash(bytes);            
  27.     string str = BitConverter.ToString(buffer2).Replace("-", "").ToLower();
  28.     return str;
  29. }
复制代码
JAVA 效果:
  1. 目标MD5 值:e10adc3949ba59abbe56e057f20f883e
  2. MD5 已匹配,对应密码:123456
  3. 结束 。
复制代码
 
 
--END
 

来源:https://www.cnblogs.com/runliuv/p/18242044
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具