C#实现WebQQ密码MD5加密算法

首先引用空间:

using System.Security.Cryptography;

WebQQ MD5加密的方式,公式是这样的:

md5(md5(hexchar2bin(md5(p)) + uin) + verify.toUpperCase());
verify是验证码,uin就是那段\x0的代码,p是密码

将普通文本转换成MD5
public static string MD5_Encrypt(string md5_str)

        {

            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5CryptoServiceProvider.Create();

            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(md5_str);

            byte[] bytes1 = md5.ComputeHash(bytes);



            System.Text.StringBuilder stringBuilder = new StringBuilder();

            foreach (var item in bytes1)

            {

                stringBuilder.Append(item.ToString("x").PadLeft(2, '0'));

            }

            return stringBuilder.ToString().ToUpper();

        }

再重载一次这个方法,以便能将字节数组也能转换成我们需要的MD5字符串

private static string MD5_Encrypt(byte[] md5_bytes)

        {

            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5CryptoServiceProvider.Create();



            byte[] bytes1 = md5.ComputeHash(md5_bytes);

            System.Text.StringBuilder stringBuilder = new StringBuilder();

            foreach (var item in bytes1)

            {

                stringBuilder.Append(item.ToString("x").PadLeft(2, '0'));

            }

            return stringBuilder.ToString().ToUpper();



        }

接着,再上一个将字符串转换为MD5加密数组的函数

/// <summary>

        /// 获取文本的md5字节流

        /// </summary>

        /// <param name="md5_str">需要加密成Md5d的文本</param>

        /// <returns></returns>

        private static byte[] MD5_GetBytes(string md5_str)

        {

            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5CryptoServiceProvider.Create();

            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(md5_str);

            return md5.ComputeHash(bytes);

        }

接下来

View Code
 1 /// <summary>
 2 
 3         /// 加密成md5字节流之后转换成文本
 4 
 5         /// </summary>
 6 
 7         /// <param name="md5_str"></param>
 8 
 9         /// <returns></returns>
10 
11         private static string Encrypt_1(string md5_str)
12 
13         {
14 
15             System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5CryptoServiceProvider.Create();
16 
17             byte[] bytes = System.Text.Encoding.ASCII.GetBytes(md5_str);
18 
19             bytes = md5.ComputeHash(bytes);
20 
21             System.Text.StringBuilder stringBuilder = new StringBuilder();
22 
23             foreach (var item in bytes)
24 
25             {
26 
27                 stringBuilder.Append(@"\x");
28 
29                 stringBuilder.Append(item.ToString("x2"));
30 
31             }
32 
33             return stringBuilder.ToString();
34 
35         }

操作字节流

View Code
  1 public class ByteBuffer
  2 
  3     {
  4 
  5         private byte[] _buffer;
  6 
  7         /// <summary>
  8 
  9         /// 获取同后备存储区连接的基础流
 10 
 11         /// </summary>
 12 
 13         public Stream BaseStream;
 14 
 15 
 16 
 17         /// <summary>
 18 
 19         /// 构造函数
 20 
 21         /// </summary>
 22 
 23         public ByteBuffer()
 24 
 25         {
 26 
 27             this.BaseStream = new MemoryStream();
 28 
 29             this._buffer = new byte[0x10];
 30 
 31         }
 32 
 33 
 34 
 35         /// <summary>
 36 
 37         /// 设置当前流中的位置
 38 
 39         /// </summary>
 40 
 41         /// <param name="offset">相对于origin参数字节偏移量</param>
 42 
 43         /// <param name="origin">System.IO.SeekOrigin类型值,指示用于获取新位置的参考点</param>
 44 
 45         /// <returns></returns>
 46 
 47         public virtual long Seek(int offset, SeekOrigin origin)
 48 
 49         {
 50 
 51             return this.BaseStream.Seek((long)offset, origin);
 52 
 53         }
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61         /// <summary>
 62 
 63         /// 检测是否还有可用字节
 64 
 65         /// </summary>
 66 
 67         /// <returns></returns>
 68 
 69         public bool Peek()
 70 
 71         {
 72 
 73             return BaseStream.Position >= BaseStream.Length ? false : true;
 74 
 75         }
 76 
 77 
 78 
 79         /// <summary>
 80 
 81         /// 将整个流内容写入字节数组,而与 Position 属性无关。
 82 
 83         /// </summary>
 84 
 85         /// <returns></returns>
 86 
 87         public byte[] ToByteArray()
 88 
 89         {
 90 
 91             long org = BaseStream.Position;
 92 
 93             BaseStream.Position = 0;
 94 
 95             byte[] ret = new byte[BaseStream.Length];
 96 
 97             BaseStream.Read(ret, 0, ret.Length);
 98 
 99             BaseStream.Position = org;
100 
101             return ret;
102 
103         }
104 
105 
106 
107 
108 
109         #region "写流方法"
110 
111         /// <summary>
112 
113         /// 压入一个布尔值,并将流中当前位置提升1
114 
115         /// </summary>
116 
117         /// <param name="value"></param>
118 
119         public void Put(bool value)
120 
121         {
122 
123             this._buffer[0] = value ? (byte)1 : (byte)0;
124 
125             this.BaseStream.Write(_buffer, 0, 1);
126 
127         }
128 
129 
130 
131         /// <summary>
132 
133         /// 压入一个Byte,并将流中当前位置提升1
134 
135         /// </summary>
136 
137         /// <param name="value"></param>
138 
139         public void Put(Byte value)
140 
141         {
142 
143             this.BaseStream.WriteByte(value);
144 
145         }
146 
147         /// <summary>
148 
149         /// 压入Byte数组,并将流中当前位置提升数组长度
150 
151         /// </summary>
152 
153         /// <param name="value">字节数组</param>
154 
155         public void Put(Byte[] value)
156 
157         {
158 
159             if (value == null)
160 
161             {
162 
163                 throw new ArgumentNullException("value");
164 
165             }
166 
167             this.BaseStream.Write(value, 0, value.Length);
168 
169         }
170 
171         /// <summary>
172 
173         /// Puts the int.
174 
175         /// </summary>
176 
177         /// <param name="value">The value.</param>
178 
179         public void PutInt(int value)
180 
181         {
182 
183             PutInt((uint)value);
184 
185         }
186 
187         /// <summary>
188 
189         /// 压入一个int,并将流中当前位置提升4
190 
191         /// </summary>
192 
193         /// <param name="value"></param>
194 
195         public void PutInt(uint value)
196 
197         {
198 
199             this._buffer[0] = (byte)(value >> 0x18);
200 
201             this._buffer[1] = (byte)(value >> 0x10);
202 
203             this._buffer[2] = (byte)(value >> 8);
204 
205             this._buffer[3] = (byte)value;
206 
207             this.BaseStream.Write(this._buffer, 0, 4);
208 
209         }
210 
211         /// <summary>
212 
213         /// Puts the int.
214 
215         /// </summary>
216 
217         /// <param name="index">The index.</param>
218 
219         /// <param name="value">The value.</param>
220 
221         public void PutInt(int index, uint value)
222 
223         {
224 
225             int pos = (int)this.BaseStream.Position;
226 
227             Seek(index, SeekOrigin.Begin);
228 
229             PutInt(value);
230 
231             Seek(pos, SeekOrigin.Begin);
232 
233         }
234 
235 
236 
237         #endregion
238 
239 
240 
241         #region "读流方法"
242 
243 
244 
245         /// <summary>
246 
247         /// 读取Byte值,并将流中当前位置提升1
248 
249         /// </summary>
250 
251         /// <returns></returns>
252 
253         public byte Get()
254 
255         {
256 
257             return (byte)BaseStream.ReadByte();
258 
259         }
260 
261 
262 
263         #endregion
264 
265 
266     }

最后一个函数

View Code
 1 public static string MD5_QQ_2_Encrypt(long uin, string password, string verifyCode)
 2 
 3         {
 4 
 5 
 6 
 7             ByteBuffer buffer= new ByteBuffer();
 8 
 9              buffer.Put(MD5_GetBytes(password));
10 
11             //buffer.Put(Encoding.UTF8.GetBytes(password));
12 
13             buffer.PutInt(0);
14 
15             buffer.PutInt((uint)uin);
16 
17             byte[] bytes = buffer.ToByteArray();
18 
19             string md5_1 = MD5_Encrypt(bytes);//将混合后的字节流进行一次md5加密
20 
21             string result= MD5_Encrypt(md5_1 + verifyCode.ToUpper());//再用加密后的结果与大写的验证码一起加密一次
22 
23             return result;
24 
25 
26 
27         }
 
原文地址:https://www.cnblogs.com/netalen/p/3014242.html