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); }
接下来
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
操作字节流
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
最后一个函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }