迷恋自留地 发表于 2020-8-11 11:41

【笔记】【ASP.NET】 常见的加密算法

# 散列运算+参数名按ASCII码从小到大排序(字典序)+签名


### 需求
1. 设所有发送或者接收到的数据为集合 M,将集合 M 内非空参数值的参数按照参数名 ASCII 码
从小到大排序(字典序),使用 URL 键值对的格式(即 key1=value1&key2=value2…)拼接成
字符串 stringA。
2. 编码成小写的 16 进制字符串






## 参数名按ASCII码从小到大排序(字典序)

在网上直找可以找到java(传送们(https://blog.csdn.net/xiaogc_a/article/details/88862678)) 的案例,c#也遇到这样的问题,那么c#如何解决呐?

```
   /// <summary>
      ///将集合 M 内非空参数值的参数按照参数名 ASCII 码从小到大排序(字典序)使用 URL 键值对的格式(即 key1=value1&key2=value2…)拼接成
      ///字符串 stringA
      /// </summary>
      /// <param name="dir"></param>
      /// <returns></returns>
      public static string AsciiDicToStr(Dictionary<string, string> dir)
      {
            string[] arrKeys = dir.Keys.ToArray();
            Array.Sort(arrKeys, string.CompareOrdinal);
            var sb = new StringBuilder();
            foreach (var key in arrKeys)
            {
                string value = dir;
                sb.Append(key + "=" + value + "&");
            }
            return sb.ToString().Substring(0, sb.ToString().Length - 1);
      }
```


##Hash (散列函数)

摘自百度 :   
Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。


---
最近遇到了一个奇奇怪怪的需求,一般关于支付或者是其他的项目会遇到,要求对数据进行散列运算,我也不太清楚是怎么运算的,但最后还是ok了,下面说明一下,

散列算法一般都会进加密(MD5 ·RSA·DSA)
下面是核心代码我具体知道里两种方法,大同小异
我测试两短代码输出结果一样,要求的是输出小写的 16 进制字符串,都实现了。

![输出结果](https://img-blog.csdnimg.cn/20200811112859631.png)
一.直接用

```
using (HashAlgorithm hash = HashAlgorithm.Create("MD5"))
            {
                string plaintext = stringA; //需要加密字符
                byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
                byte[] hashValueBytes = hash.ComputeHash(plaintextBytes);
                string hashValue = BitConverter.ToString(hashValueBytes).Replace("-", "");
               // sing = hashValue.ToLower(); 定义的变量,转化为小写(也可能为大写)
                Console.WriteLine(hashValue);
            }
```

二.封装为方法

```
      public static string MD5Encrypt32(string password)
      {
            //密文
            string pwd = string.Empty;
            //实例化一个md5对像
            MD5 md5 = MD5.Create();
            // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 
            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(password));
            // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
            for (int i = 0; i < s.Length; i++)
            {
                // 将得到的字符串使用十六进制类型格式。
                //格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
                //X2表示16进制
                pwd = pwd + s.ToString("X2");
            }
            return pwd;
      }

```

#### 如果觉得我写的还可以的话,或者有用到的话,麻烦给我点个赞,你的支持会带来更多的知识

sgh2zlx 发表于 2020-8-11 13:06

不错不错

zpy2 发表于 2020-8-11 15:18

不错,不错,谢谢分享

Light紫星 发表于 2020-8-11 15:30

不错,第一个好多软件都在用

goodista 发表于 2020-8-30 15:46

不错不错

sweet_love 发表于 2020-11-21 16:23

建议楼主直接出一个工具类。
页: [1]
查看完整版本: 【笔记】【ASP.NET】 常见的加密算法