浅谈OAuth2.0认证

       现在的网站越来越多的用到第三方登陆,现在提供第三方登陆api接口的网站包括新浪微博,腾讯,网易,开心,人人但是就本人的观点来看里面最安全的第三方应该说是人人提供的接口了,因为本人在调用人人提供的api接口时费了很大的劲,因为他需要签名认证

      但是使用OAuth2.0的标准是都一样的

1、通过OAuth2/authorize接口获取code

2、通过OAuth2/access_token获取accesstoken,因为有些api中都含有唯一确定用户的信息包括uid,因为每次调用其他的接口时还要需要到access_token,所以access_token是非常重要的,但是他有过期时间一般10到15天,有的接口中有freshtoken

上面一般接口调用都非常简单下面来贴段人人获取签名认证的代码,来帮助有需要的人使用

View Code
  1     public class GetSig
  2     {
  3         #region 加密编码
  4         // MD5 加密
  5         public static string MD5Encrpt(string plainText)
  6         {
  7             return MD5CryptoServiceProvider.GetMd5String(plainText);
  8         }
  9 
 10         // utf-8编码
 11         public static string Utf8Encode(string plainText)
 12         {
 13             if (plainText == null) plainText = " ";
 14             byte[] b = System.Text.Encoding.UTF8.GetBytes(plainText);
 15             string retString = System.Text.Encoding.UTF8.GetString(b, 0, b.Length);
 16             return retString;
 17         }
 18         #endregion
 19         #region 计算sig签名的方法
 20         /// <summary>
 21         /// 计算签名
 22         /// 此方法传入的是所有签名需要的参数
 23         /// </summary>
 24         /// <param name="paras">传入需要的参数</param>
 25         /// <returns></returns>
 26         public static string CalSig(List<APIParameter> paras)
 27         {
 28             //List<APIParameter> paras = new List<APIParameter>();
 29             //paras.Add(new APIParameter("v", "1.0"));
 30             //paras.Add(new APIParameter("api_key", "ec9e57913c5b42b282ab7b743559e1b0"));
 31             //paras.Add(new APIParameter("method", "users.getLoggedInUser"));
 32             //paras.Add(new APIParameter("call_id", "1232095295656"));
 33             //paras.Add(new APIParameter("session_key", "L6Xe8dXVGISZ17LJy7GzZaeYGpeGfeNdqEPLNUtCJfxPCxCRLWT83x+s/Ur94PqP-700001044"));
 34             paras.Sort(new ParameterComparer());
 35             StringBuilder sbList = new StringBuilder();
 36             foreach (APIParameter para in paras)
 37             {
 38                 sbList.AppendFormat("{0}={1}", para.Name, para.Value);
 39             }
 40             var appSettings = new AppSettings();
 41              var AppSecret = appSettings.GetString("renren.AppSecret");
 42             sbList.Append(AppSecret);
 43             string a = MD5Encrpt(sbList.ToString());
 44             return a;
 45         }
 46 
 47         /// <summary>
 48         /// 不区分大小写,获得querysring中的值
 49         /// </summary>
 50         /// <param name="url"></param>
 51         /// <param name="key"></param>
 52         /// <returns></returns>
 53         public static string GetQueryString(Uri url, string key)
 54         {
 55             string retVal = "";
 56             string query = "";
 57             string abUrl = url.Fragment;
 58 
 59             if (abUrl != "")
 60             {
 61                 abUrl = Uri.UnescapeDataString(abUrl);
 62                 query = abUrl.Replace("#", "");
 63             }
 64             else
 65             {
 66                 abUrl = url.AbsoluteUri;
 67                 abUrl = Uri.UnescapeDataString(abUrl);
 68                 query = abUrl.Substring(abUrl.IndexOf("?") + 1);
 69                 query = query.Replace("?", "");
 70             }
 71 
 72             string[] querys = query.Split('&');
 73             foreach (string qu in querys)
 74             {
 75                 string[] vals = qu.Split('=');
 76                 if (vals[0].ToString().ToLower() == key.ToLower())
 77                 {
 78                     retVal = vals[1].ToString();
 79                     break;
 80                 }
 81             }
 82             return retVal;
 83         }
 84 
 85         #endregion
 86 
 87     }
 88      public class APIParameter
 89     {
 90         private string name = null;
 91         private string value = null;
 92 
 93         public APIParameter(string name, string value)
 94         {
 95             this.name = name;
 96             this.value = value;
 97         }
 98 
 99         public string Name
100         {
101             get { return name; }
102         }
103 
104         public string Value
105         {
106             get { return value; }
107         }
108     }
109 
110     /// <summary>
111     /// Comparer class used to perform the sorting of the query parameters
112     /// </summary>
113     public class ParameterComparer : IComparer<APIParameter>
114     {
115         public int Compare(APIParameter x, APIParameter y)
116         {
117             if (x.Name == y.Name)
118             {
119                 return string.Compare(x.Value, y.Value);
120             }
121             else
122             {
123                 return string.Compare(x.Name, y.Name);
124             }
125         }
126     }
127 
128 
129     public class MD5CryptoServiceProvider : MD5
130     {
131         public MD5CryptoServiceProvider()
132             : base()
133         {
134         }
135     }
136     /// <summary>
137     /// Summary description for MD5.
138     /// </summary>
139    public class MD5 : IDisposable
140     {
141         static public MD5 Create(string hashName)
142         {
143             if (hashName == "MD5")
144                 return new MD5();
145             else
146                 throw new NotSupportedException();
147         }
148 
149         static public String GetMd5String(String source)
150         {
151             MD5 md = MD5CryptoServiceProvider.Create();
152             byte[] hash;
153 
154             //Create a new instance of ASCIIEncoding to 
155             //convert the string into an array of Unicode bytes.
156             UTF8Encoding enc = new UTF8Encoding();
157             //            ASCIIEncoding enc = new ASCIIEncoding();
158 
159             //Convert the string into an array of bytes.
160             byte[] buffer = enc.GetBytes(source);
161 
162             //Create the hash value from the array of bytes.
163             hash = md.ComputeHash(buffer);
164 
165             StringBuilder sb = new StringBuilder();
166             foreach (byte b in hash)
167                 sb.Append(b.ToString("x2"));
168             return sb.ToString();
169         }
170 
171         static public MD5 Create()
172         {
173             return new MD5();
174         }
175 
176         #region base implementation of the MD5
177         #region constants
178         private const byte S11 = 7;
179         private const byte S12 = 12;
180         private const byte S13 = 17;
181         private const byte S14 = 22;
182         private const byte S21 = 5;
183         private const byte S22 = 9;
184         private const byte S23 = 14;
185         private const byte S24 = 20;
186         private const byte S31 = 4;
187         private const byte S32 = 11;
188         private const byte S33 = 16;
189         private const byte S34 = 23;
190         private const byte S41 = 6;
191         private const byte S42 = 10;
192         private const byte S43 = 15;
193         private const byte S44 = 21;
194         static private byte[] PADDING = new byte[] {
195               0x80, 0, 0, 0, 0, 0, 
196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197               0, 0, 0, 0, 0, 0, 0, 
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
199               0, 0, 0, 0, 0, 0, 0, 
200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
201              };
202         #endregion
203 
204         #region F, G, H and I are basic MD5 functions.
205         static private uint F(uint x, uint y, uint z)
206         {
207             return (((x) & (y)) | ((~x) & (z)));
208         }
209         static private uint G(uint x, uint y, uint z)
210         {
211             return (((x) & (z)) | ((y) & (~z)));
212         }
213         static private uint H(uint x, uint y, uint z)
214         {
215             return ((x) ^ (y) ^ (z));
216         }
217         static private uint I(uint x, uint y, uint z)
218         {
219             return ((y) ^ ((x) | (~z)));
220         }
221         #endregion
222 
223         #region rotates x left n bits.
224         /// <summary>
225         /// rotates x left n bits.
226         /// </summary>
227         /// <param name="x"></param>
228         /// <param name="n"></param>
229         /// <returns></returns>
230         static private uint ROTATE_LEFT(uint x, byte n)
231         {
232             return (((x) << (n)) | ((x) >> (32 - (n))));
233         }
234         #endregion
235 
236         #region FF, GG, HH, and II transformations
237         /// FF, GG, HH, and II transformations 
238         /// for rounds 1, 2, 3, and 4.
239         /// Rotation is separate from addition to prevent recomputation.
240         static private void FF(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac)
241         {
242             (a) += F((b), (c), (d)) + (x) + (uint)(ac);
243             (a) = ROTATE_LEFT((a), (s));
244             (a) += (b);
245         }
246         static private void GG(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac)
247         {
248             (a) += G((b), (c), (d)) + (x) + (uint)(ac);
249             (a) = ROTATE_LEFT((a), (s));
250             (a) += (b);
251         }
252         static private void HH(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac)
253         {
254             (a) += H((b), (c), (d)) + (x) + (uint)(ac);
255             (a) = ROTATE_LEFT((a), (s));
256             (a) += (b);
257         }
258         static private void II(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac)
259         {
260             (a) += I((b), (c), (d)) + (x) + (uint)(ac);
261             (a) = ROTATE_LEFT((a), (s));
262             (a) += (b);
263         }
264         #endregion
265 
266         #region context info
267         /// <summary>
268         /// state (ABCD)
269         /// </summary>
270         uint[] state = new uint[4];
271 
272         /// <summary>
273         /// number of bits, modulo 2^64 (lsb first)
274         /// </summary>
275         uint[] count = new uint[2];
276 
277         /// <summary>
278         /// input buffer
279         /// </summary>
280         byte[] buffer = new byte[64];
281         #endregion
282 
283         internal MD5()
284         {
285             Initialize();
286         }
287 
288         /// <summary>
289         /// MD5 initialization. Begins an MD5 operation, writing a new context.
290         /// </summary>
291         /// <remarks>
292         /// The RFC named it "MD5Init"
293         /// </remarks>
294         public virtual void Initialize()
295         {
296             count[0] = count[1] = 0;
297 
298             // Load magic initialization constants.
299             state[0] = 0x67452301;
300             state[1] = 0xefcdab89;
301             state[2] = 0x98badcfe;
302             state[3] = 0x10325476;
303         }
304 
305         /// <summary>
306         /// MD5 block update operation. Continues an MD5 message-digest
307         /// operation, processing another message block, and updating the
308         /// context.
309         /// </summary>
310         /// <param name="input"></param>
311         /// <param name="offset"></param>
312         /// <param name="count"></param>
313         /// <remarks>The RFC Named it MD5Update</remarks>
314         protected virtual void HashCore(byte[] input, int offset, int count)
315         {
316             int i;
317             int index;
318             int partLen;
319 
320             // Compute number of bytes mod 64
321             index = (int)((this.count[0] >> 3) & 0x3F);
322 
323             // Update number of bits
324             if ((this.count[0] += (uint)((uint)count << 3)) < ((uint)count << 3))
325                 this.count[1]++;
326             this.count[1] += ((uint)count >> 29);
327 
328             partLen = 64 - index;
329 
330             // Transform as many times as possible.
331             if (count >= partLen)
332             {
333                 Buffer.BlockCopy(input, offset, this.buffer, index, partLen);
334                 Transform(this.buffer, 0);
335 
336                 for (i = partLen; i + 63 < count; i += 64)
337                     Transform(input, offset + i);
338 
339                 index = 0;
340             }
341             else
342                 i = 0;
343 
344             // Buffer remaining input 
345             Buffer.BlockCopy(input, offset + i, this.buffer, index, count - i);
346         }
347 
348         /// <summary>
349         /// MD5 finalization. Ends an MD5 message-digest operation, writing the
350         /// the message digest and zeroizing the context.
351         /// </summary>
352         /// <returns>message digest</returns>
353         /// <remarks>The RFC named it MD5Final</remarks>
354         protected virtual byte[] HashFinal()
355         {
356             byte[] digest = new byte[16];
357             byte[] bits = new byte[8];
358             int index, padLen;
359 
360             // Save number of bits
361             Encode(bits, 0, this.count, 0, 8);
362 
363             // Pad out to 56 mod 64.
364             index = (int)((uint)(this.count[0] >> 3) & 0x3f);
365             padLen = (index < 56) ? (56 - index) : (120 - index);
366             HashCore(PADDING, 0, padLen);
367 
368             // Append length (before padding)
369             HashCore(bits, 0, 8);
370 
371             // Store state in digest 
372             Encode(digest, 0, state, 0, 16);
373 
374             // Zeroize sensitive information.
375             count[0] = count[1] = 0;
376             state[0] = 0;
377             state[1] = 0;
378             state[2] = 0;
379             state[3] = 0;
380 
381             // initialize again, to be ready to use
382             Initialize();
383 
384             return digest;
385         }
386 
387         /// <summary>
388         /// MD5 basic transformation. Transforms state based on 64 bytes block.
389         /// </summary>
390         /// <param name="block"></param>
391         /// <param name="offset"></param>
392         private void Transform(byte[] block, int offset)
393         {
394             uint a = state[0], b = state[1], c = state[2], d = state[3];
395             uint[] x = new uint[16];
396             Decode(x, 0, block, offset, 64);
397 
398             // Round 1
399             FF(ref a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
400             FF(ref d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
401             FF(ref c, d, a, b, x[2], S13, 0x242070db); /* 3 */
402             FF(ref b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
403             FF(ref a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
404             FF(ref d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
405             FF(ref c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
406             FF(ref b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
407             FF(ref a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
408             FF(ref d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
409             FF(ref c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
410             FF(ref b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
411             FF(ref a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
412             FF(ref d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
413             FF(ref c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
414             FF(ref b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
415 
416             // Round 2
417             GG(ref a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
418             GG(ref d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
419             GG(ref c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
420             GG(ref b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
421             GG(ref a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
422             GG(ref d, a, b, c, x[10], S22, 0x2441453); /* 22 */
423             GG(ref c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
424             GG(ref b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
425             GG(ref a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
426             GG(ref d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
427             GG(ref c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
428             GG(ref b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
429             GG(ref a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
430             GG(ref d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
431             GG(ref c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
432             GG(ref b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
433 
434             // Round 3
435             HH(ref a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
436             HH(ref d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
437             HH(ref c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
438             HH(ref b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
439             HH(ref a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
440             HH(ref d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
441             HH(ref c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
442             HH(ref b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
443             HH(ref a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
444             HH(ref d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
445             HH(ref c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
446             HH(ref b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
447             HH(ref a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
448             HH(ref d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
449             HH(ref c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
450             HH(ref b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
451 
452             // Round 4
453             II(ref a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
454             II(ref d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
455             II(ref c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
456             II(ref b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
457             II(ref a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
458             II(ref d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
459             II(ref c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
460             II(ref b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
461             II(ref a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
462             II(ref d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
463             II(ref c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
464             II(ref b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
465             II(ref a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
466             II(ref d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
467             II(ref c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
468             II(ref b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
469 
470             state[0] += a;
471             state[1] += b;
472             state[2] += c;
473             state[3] += d;
474 
475             // Zeroize sensitive information.
476             for (int i = 0; i < x.Length; i++)
477                 x[i] = 0;
478         }
479 
480         /// <summary>
481         /// Encodes input (uint) into output (byte). Assumes len is
482         ///  multiple of 4.
483         /// </summary>
484         /// <param name="output"></param>
485         /// <param name="outputOffset"></param>
486         /// <param name="input"></param>
487         /// <param name="inputOffset"></param>
488         /// <param name="count"></param>
489         private static void Encode(byte[] output, int outputOffset, uint[] input, int inputOffset, int count)
490         {
491             int i, j;
492             int end = outputOffset + count;
493             for (i = inputOffset, j = outputOffset; j < end; i++, j += 4)
494             {
495                 output[j] = (byte)(input[i] & 0xff);
496                 output[j + 1] = (byte)((input[i] >> 8) & 0xff);
497                 output[j + 2] = (byte)((input[i] >> 16) & 0xff);
498                 output[j + 3] = (byte)((input[i] >> 24) & 0xff);
499             }
500         }
501 
502         /// <summary>
503         /// Decodes input (byte) into output (uint). Assumes len is
504         /// a multiple of 4.
505         /// </summary>
506         /// <param name="output"></param>
507         /// <param name="outputOffset"></param>
508         /// <param name="input"></param>
509         /// <param name="inputOffset"></param>
510         /// <param name="count"></param>
511         static private void Decode(uint[] output, int outputOffset, byte[] input, int inputOffset, int count)
512         {
513             int i, j;
514             int end = inputOffset + count;
515             for (i = outputOffset, j = inputOffset; j < end; i++, j += 4)
516                 output[i] = ((uint)input[j]) | (((uint)input[j + 1]) << 8) | (((uint)input[j + 2]) << 16) | (((uint)input[j + 3]) <<
517 24);
518         }
519         #endregion
520 
521         #region expose the same interface as the regular MD5 object
522 
523         protected byte[] HashValue;
524         protected int State;
525         public virtual bool CanReuseTransform
526         {
527             get
528             {
529                 return true;
530             }
531         }
532 
533         public virtual bool CanTransformMultipleBlocks
534         {
535             get
536             {
537                 return true;
538             }
539         }
540         public virtual byte[] Hash
541         {
542             get
543             {
544                 if (this.State != 0)
545                     throw new InvalidOperationException();
546                 return (byte[])HashValue.Clone();
547             }
548         }
549         public virtual int HashSize
550         {
551             get
552             {
553                 return HashSizeValue;
554             }
555         }
556         protected int HashSizeValue = 128;
557 
558         public virtual int InputBlockSize
559         {
560             get
561             {
562                 return 1;
563             }
564         }
565         public virtual int OutputBlockSize
566         {
567             get
568             {
569                 return 1;
570             }
571         }
572 
573         public void Clear()
574         {
575             Dispose(true);
576         }
577 
578         public byte[] ComputeHash(byte[] buffer)
579         {
580             return ComputeHash(buffer, 0, buffer.Length);
581         }
582         public byte[] ComputeHash(byte[] buffer, int offset, int count)
583         {
584             Initialize();
585             HashCore(buffer, offset, count);
586             HashValue = HashFinal();
587             return (byte[])HashValue.Clone();
588         }
589 
590         public byte[] ComputeHash(Stream inputStream)
591         {
592             Initialize();
593             int count = 0;
594             byte[] buffer = new byte[4096];
595             while (0 < (count = inputStream.Read(buffer, 0, 4096)))
596             {
597                 HashCore(buffer, 0, count);
598             }
599             HashValue = HashFinal();
600             return (byte[])HashValue.Clone();
601         }
602 
603         public int TransformBlock(
604             byte[] inputBuffer,
605             int inputOffset,
606             int inputCount,
607             byte[] outputBuffer,
608             int outputOffset
609             )
610         {
611             if (inputBuffer == null)
612             {
613                 throw new ArgumentNullException("inputBuffer");
614             }
615             if (inputOffset < 0)
616             {
617                 throw new ArgumentOutOfRangeException("inputOffset");
618             }
619             if ((inputCount < 0) || (inputCount > inputBuffer.Length))
620             {
621                 throw new ArgumentException("inputCount");
622             }
623             if ((inputBuffer.Length - inputCount) < inputOffset)
624             {
625                 throw new ArgumentOutOfRangeException("inputOffset");
626             }
627             if (this.State == 0)
628             {
629                 Initialize();
630                 this.State = 1;
631             }
632 
633             HashCore(inputBuffer, inputOffset, inputCount);
634             if ((inputBuffer != outputBuffer) || (inputOffset != outputOffset))
635             {
636                 Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
637             }
638             return inputCount;
639         }
640         public byte[] TransformFinalBlock(
641             byte[] inputBuffer,
642             int inputOffset,
643             int inputCount
644             )
645         {
646             if (inputBuffer == null)
647             {
648                 throw new ArgumentNullException("inputBuffer");
649             }
650             if (inputOffset < 0)
651             {
652                 throw new ArgumentOutOfRangeException("inputOffset");
653             }
654             if ((inputCount < 0) || (inputCount > inputBuffer.Length))
655             {
656                 throw new ArgumentException("inputCount");
657             }
658             if ((inputBuffer.Length - inputCount) < inputOffset)
659             {
660                 throw new ArgumentOutOfRangeException("inputOffset");
661             }
662             if (this.State == 0)
663             {
664                 Initialize();
665             }
666             HashCore(inputBuffer, inputOffset, inputCount);
667             HashValue = HashFinal();
668             byte[] buffer = new byte[inputCount];
669             Buffer.BlockCopy(inputBuffer, inputOffset, buffer, 0, inputCount);
670             this.State = 0;
671             return buffer;
672         }
673         #endregion
674 
675         protected virtual void Dispose(bool disposing)
676         {
677             if (!disposing)
678                 Initialize();
679         }
680         public void Dispose()
681         {
682             Dispose(true);
683         }
684     }
posted @ 2012-10-20 21:35  win_and_first  阅读(1238)  评论(0编辑  收藏  举报