[Silverlight] 在Silverlight 中做MD5編碼
2010/10/13
有時候會需要前端送資料給Server的時候..
做一些資料的驗證..尤其是串金流時偶會用到..
基本上在Silverlight中沒有提供..
但是社群力量是偉大的..
有提供出一段Source 我測試了一下…
下面會附上還有ASP.net 的Code …
編碼出來的MD5是一樣的.
就順便附上 …
這樣讓你在寫Server端這邊程式…
才可以一致..
網路上的 : MD5CryptoServiceProvider
1: using System;
2: using System.IO;
3: using System.Text;
4:
5: namespace MD5_Sample
6: {
7: public class MD5CryptoServiceProvider : MD5
8: {
9: public MD5CryptoServiceProvider()
10: : base()
11: {
12: }
13: }
14: /// <summary>
15: /// Summary description for MD5.
16: /// </summary>
17: public class MD5 : IDisposable
18: {
19: static public MD5 Create(string hashName)
20: {
21: if (hashName == "MD5")
22: return new MD5();
23: else
24: throw new NotSupportedException();
25: }
26:
27: static public String GetMd5String(String source)
28: {
29: MD5 md = MD5CryptoServiceProvider.Create();
30: byte[] hash;
31:
32: //Create a new instance of ASCIIEncoding to
33: //convert the string into an array of Unicode bytes.
34: UTF8Encoding enc = new UTF8Encoding();
35: // ASCIIEncoding enc = new ASCIIEncoding();
36:
37: //Convert the string into an array of bytes.
38: byte[] buffer = enc.GetBytes(source);
39:
40: //Create the hash value from the array of bytes.
41: hash = md.ComputeHash(buffer);
42:
43: StringBuilder sb = new StringBuilder();
44: foreach (byte b in hash)
45: sb.Append(b.ToString("x2"));
46: return sb.ToString();
47: }
48:
49: static public MD5 Create()
50: {
51: return new MD5();
52: }
53:
54: #region base implementation of the MD5
55: #region constants
56: private const byte S11 = 7;
57: private const byte S12 = 12;
58: private const byte S13 = 17;
59: private const byte S14 = 22;
60: private const byte S21 = 5;
61: private const byte S22 = 9;
62: private const byte S23 = 14;
63: private const byte S24 = 20;
64: private const byte S31 = 4;
65: private const byte S32 = 11;
66: private const byte S33 = 16;
67: private const byte S34 = 23;
68: private const byte S41 = 6;
69: private const byte S42 = 10;
70: private const byte S43 = 15;
71: private const byte S44 = 21;
72: static private byte[] PADDING = new byte[] {
73: 0x80, 0, 0, 0, 0, 0,
74: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75: 0, 0, 0, 0, 0, 0, 0,
76: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77: 0, 0, 0, 0, 0, 0, 0,
78: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
79: };
80: #endregion
81:
82: #region F, G, H and I are basic MD5 functions.
83: static private uint F(uint x, uint y, uint z)
84: {
85: return (((x) & (y)) | ((~x) & (z)));
86: }
87: static private uint G(uint x, uint y, uint z)
88: {
89: return (((x) & (z)) | ((y) & (~z)));
90: }
91: static private uint H(uint x, uint y, uint z)
92: {
93: return ((x) ^ (y) ^ (z));
94: }
95: static private uint I(uint x, uint y, uint z)
96: {
97: return ((y) ^ ((x) | (~z)));
98: }
99: #endregion
100:
101: #region rotates x left n bits.
102: /// <summary>
103: /// rotates x left n bits.
104: /// </summary>
105: /// <param name="x"></param>
106: /// <param name="n"></param>
107: /// <returns></returns>
108: static private uint ROTATE_LEFT(uint x, byte n)
109: {
110: return (((x) << (n)) | ((x) >> (32 - (n))));
111: }
112: #endregion
113:
114: #region FF, GG, HH, and II transformations
115: /// FF, GG, HH, and II transformations
116: /// for rounds 1, 2, 3, and 4.
117: /// Rotation is separate from addition to prevent recomputation.
118: static private void FF(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac)
119: {
120: (a) += F((b), (c), (d)) + (x) + (uint)(ac);
121: (a) = ROTATE_LEFT((a), (s));
122: (a) += (b);
123: }
124: static private void GG(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac)
125: {
126: (a) += G((b), (c), (d)) + (x) + (uint)(ac);
127: (a) = ROTATE_LEFT((a), (s));
128: (a) += (b);
129: }
130: static private void HH(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac)
131: {
132: (a) += H((b), (c), (d)) + (x) + (uint)(ac);
133: (a) = ROTATE_LEFT((a), (s));
134: (a) += (b);
135: }
136: static private void II(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac)
137: {
138: (a) += I((b), (c), (d)) + (x) + (uint)(ac);
139: (a) = ROTATE_LEFT((a), (s));
140: (a) += (b);
141: }
142: #endregion
143:
144: #region context info
145: /// <summary>
146: /// state (ABCD)
147: /// </summary>
148: uint[] state = new uint[4];
149:
150: /// <summary>
151: /// number of bits, modulo 2^64 (lsb first)
152: /// </summary>
153: uint[] count = new uint[2];
154:
155: /// <summary>
156: /// input buffer
157: /// </summary>
158: byte[] buffer = new byte[64];
159: #endregion
160:
161: internal MD5()
162: {
163: Initialize();
164: }
165:
166: /// <summary>
167: /// MD5 initialization. Begins an MD5 operation, writing a new context.
168: /// </summary>
169: /// <remarks>
170: /// The RFC named it "MD5Init"
171: /// </remarks>
172: public virtual void Initialize()
173: {
174: count[0] = count[1] = 0;
175:
176: // Load magic initialization constants.
177: state[0] = 0x67452301;
178: state[1] = 0xefcdab89;
179: state[2] = 0x98badcfe;
180: state[3] = 0x10325476;
181: }
182:
183: /// <summary>
184: /// MD5 block update operation. Continues an MD5 message-digest
185: /// operation, processing another message block, and updating the
186: /// context.
187: /// </summary>
188: /// <param name="input"></param>
189: /// <param name="offset"></param>
190: /// <param name="count"></param>
191: /// <remarks>The RFC Named it MD5Update</remarks>
192: protected virtual void HashCore(byte[] input, int offset, int count)
193: {
194: int i;
195: int index;
196: int partLen;
197:
198: // Compute number of bytes mod 64
199: index = (int)((this.count[0] >> 3) & 0x3F);
200:
201: // Update number of bits
202: if ((this.count[0] += (uint)((uint)count << 3)) < ((uint)count << 3))
203: this.count[1]++;
204: this.count[1] += ((uint)count >> 29);
205:
206: partLen = 64 - index;
207:
208: // Transform as many times as possible.
209: if (count >= partLen)
210: {
211: Buffer.BlockCopy(input, offset, this.buffer, index, partLen);
212: Transform(this.buffer, 0);
213:
214: for (i = partLen; i + 63 < count; i += 64)
215: Transform(input, offset + i);
216:
217: index = 0;
218: }
219: else
220: i = 0;
221:
222: // Buffer remaining input
223: Buffer.BlockCopy(input, offset + i, this.buffer, index, count - i);
224: }
225:
226: /// <summary>
227: /// MD5 finalization. Ends an MD5 message-digest operation, writing the
228: /// the message digest and zeroizing the context.
229: /// </summary>
230: /// <returns>message digest</returns>
231: /// <remarks>The RFC named it MD5Final</remarks>
232: protected virtual byte[] HashFinal()
233: {
234: byte[] digest = new byte[16];
235: byte[] bits = new byte[8];
236: int index, padLen;
237:
238: // Save number of bits
239: Encode(bits, 0, this.count, 0, 8);
240:
241: // Pad out to 56 mod 64.
242: index = (int)((uint)(this.count[0] >> 3) & 0x3f);
243: padLen = (index < 56) ? (56 - index) : (120 - index);
244: HashCore(PADDING, 0, padLen);
245:
246: // Append length (before padding)
247: HashCore(bits, 0, 8);
248:
249: // Store state in digest
250: Encode(digest, 0, state, 0, 16);
251:
252: // Zeroize sensitive information.
253: count[0] = count[1] = 0;
254: state[0] = 0;
255: state[1] = 0;
256: state[2] = 0;
257: state[3] = 0;
258:
259: // initialize again, to be ready to use
260: Initialize();
261:
262: return digest;
263: }
264:
265: /// <summary>
266: /// MD5 basic transformation. Transforms state based on 64 bytes block.
267: /// </summary>
268: /// <param name="block"></param>
269: /// <param name="offset"></param>
270: private void Transform(byte[] block, int offset)
271: {
272: uint a = state[0], b = state[1], c = state[2], d = state[3];
273: uint[] x = new uint[16];
274: Decode(x, 0, block, offset, 64);
275:
276: // Round 1
277: FF(ref a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
278: FF(ref d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
279: FF(ref c, d, a, b, x[2], S13, 0x242070db); /* 3 */
280: FF(ref b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
281: FF(ref a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
282: FF(ref d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
283: FF(ref c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
284: FF(ref b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
285: FF(ref a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
286: FF(ref d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
287: FF(ref c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
288: FF(ref b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
289: FF(ref a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
290: FF(ref d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
291: FF(ref c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
292: FF(ref b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
293:
294: // Round 2
295: GG(ref a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
296: GG(ref d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
297: GG(ref c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
298: GG(ref b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
299: GG(ref a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
300: GG(ref d, a, b, c, x[10], S22, 0x2441453); /* 22 */
301: GG(ref c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
302: GG(ref b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
303: GG(ref a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
304: GG(ref d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
305: GG(ref c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
306: GG(ref b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
307: GG(ref a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
308: GG(ref d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
309: GG(ref c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
310: GG(ref b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
311:
312: // Round 3
313: HH(ref a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
314: HH(ref d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
315: HH(ref c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
316: HH(ref b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
317: HH(ref a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
318: HH(ref d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
319: HH(ref c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
320: HH(ref b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
321: HH(ref a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
322: HH(ref d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
323: HH(ref c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
324: HH(ref b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
325: HH(ref a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
326: HH(ref d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
327: HH(ref c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
328: HH(ref b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
329:
330: // Round 4
331: II(ref a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
332: II(ref d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
333: II(ref c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
334: II(ref b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
335: II(ref a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
336: II(ref d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
337: II(ref c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
338: II(ref b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
339: II(ref a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
340: II(ref d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
341: II(ref c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
342: II(ref b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
343: II(ref a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
344: II(ref d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
345: II(ref c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
346: II(ref b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
347:
348: state[0] += a;
349: state[1] += b;
350: state[2] += c;
351: state[3] += d;
352:
353: // Zeroize sensitive information.
354: for (int i = 0; i < x.Length; i++)
355: x[i] = 0;
356: }
357:
358: /// <summary>
359: /// Encodes input (uint) into output (byte). Assumes len is
360: /// multiple of 4.
361: /// </summary>
362: /// <param name="output"></param>
363: /// <param name="outputOffset"></param>
364: /// <param name="input"></param>
365: /// <param name="inputOffset"></param>
366: /// <param name="count"></param>
367: private static void Encode(byte[] output, int outputOffset, uint[] input, int inputOffset, int count)
368: {
369: int i, j;
370: int end = outputOffset + count;
371: for (i = inputOffset, j = outputOffset; j < end; i++, j += 4)
372: {
373: output[j] = (byte)(input[i] & 0xff);
374: output[j + 1] = (byte)((input[i] >> 8) & 0xff);
375: output[j + 2] = (byte)((input[i] >> 16) & 0xff);
376: output[j + 3] = (byte)((input[i] >> 24) & 0xff);
377: }
378: }
379:
380: /// <summary>
381: /// Decodes input (byte) into output (uint). Assumes len is
382: /// a multiple of 4.
383: /// </summary>
384: /// <param name="output"></param>
385: /// <param name="outputOffset"></param>
386: /// <param name="input"></param>
387: /// <param name="inputOffset"></param>
388: /// <param name="count"></param>
389: static private void Decode(uint[] output, int outputOffset, byte[] input, int inputOffset, int count)
390: {
391: int i, j;
392: int end = inputOffset + count;
393: for (i = outputOffset, j = inputOffset; j < end; i++, j += 4)
394: output[i] = ((uint)input[j]) | (((uint)input[j + 1]) << 8) | (((uint)input[j + 2]) << 16) | (((uint)input[j + 3]) <<
395: 24);
396: }
397: #endregion
398:
399: #region expose the same interface as the regular MD5 object
400:
401: protected byte[] HashValue;
402: protected int State;
403: public virtual bool CanReuseTransform
404: {
405: get
406: {
407: return true;
408: }
409: }
410:
411: public virtual bool CanTransformMultipleBlocks
412: {
413: get
414: {
415: return true;
416: }
417: }
418: public virtual byte[] Hash
419: {
420: get
421: {
422: if (this.State != 0)
423: throw new InvalidOperationException();
424: return (byte[])HashValue.Clone();
425: }
426: }
427: public virtual int HashSize
428: {
429: get
430: {
431: return HashSizeValue;
432: }
433: }
434: protected int HashSizeValue = 128;
435:
436: public virtual int InputBlockSize
437: {
438: get
439: {
440: return 1;
441: }
442: }
443: public virtual int OutputBlockSize
444: {
445: get
446: {
447: return 1;
448: }
449: }
450:
451: public void Clear()
452: {
453: Dispose(true);
454: }
455:
456: public byte[] ComputeHash(byte[] buffer)
457: {
458: return ComputeHash(buffer, 0, buffer.Length);
459: }
460: public byte[] ComputeHash(byte[] buffer, int offset, int count)
461: {
462: Initialize();
463: HashCore(buffer, offset, count);
464: HashValue = HashFinal();
465: return (byte[])HashValue.Clone();
466: }
467:
468: public byte[] ComputeHash(Stream inputStream)
469: {
470: Initialize();
471: int count = 0;
472: byte[] buffer = new byte[4096];
473: while (0 < (count = inputStream.Read(buffer, 0, 4096)))
474: {
475: HashCore(buffer, 0, count);
476: }
477: HashValue = HashFinal();
478: return (byte[])HashValue.Clone();
479: }
480:
481: public int TransformBlock(
482: byte[] inputBuffer,
483: int inputOffset,
484: int inputCount,
485: byte[] outputBuffer,
486: int outputOffset
487: )
488: {
489: if (inputBuffer == null)
490: {
491: throw new ArgumentNullException("inputBuffer");
492: }
493: if (inputOffset < 0)
494: {
495: throw new ArgumentOutOfRangeException("inputOffset");
496: }
497: if ((inputCount < 0) || (inputCount > inputBuffer.Length))
498: {
499: throw new ArgumentException("inputCount");
500: }
501: if ((inputBuffer.Length - inputCount) < inputOffset)
502: {
503: throw new ArgumentOutOfRangeException("inputOffset");
504: }
505: if (this.State == 0)
506: {
507: Initialize();
508: this.State = 1;
509: }
510:
511: HashCore(inputBuffer, inputOffset, inputCount);
512: if ((inputBuffer != outputBuffer) || (inputOffset != outputOffset))
513: {
514: Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
515: }
516: return inputCount;
517: }
518: public byte[] TransformFinalBlock(
519: byte[] inputBuffer,
520: int inputOffset,
521: int inputCount
522: )
523: {
524: if (inputBuffer == null)
525: {
526: throw new ArgumentNullException("inputBuffer");
527: }
528: if (inputOffset < 0)
529: {
530: throw new ArgumentOutOfRangeException("inputOffset");
531: }
532: if ((inputCount < 0) || (inputCount > inputBuffer.Length))
533: {
534: throw new ArgumentException("inputCount");
535: }
536: if ((inputBuffer.Length - inputCount) < inputOffset)
537: {
538: throw new ArgumentOutOfRangeException("inputOffset");
539: }
540: if (this.State == 0)
541: {
542: Initialize();
543: }
544: HashCore(inputBuffer, inputOffset, inputCount);
545: HashValue = HashFinal();
546: byte[] buffer = new byte[inputCount];
547: Buffer.BlockCopy(inputBuffer, inputOffset, buffer, 0, inputCount);
548: this.State = 0;
549: return buffer;
550: }
551: #endregion
552:
553: protected virtual void Dispose(bool disposing)
554: {
555: if (!disposing)
556: Initialize();
557: }
558: public void Dispose()
559: {
560: Dispose(true);
561: }
562: }
563:
564:
565: }
之後我們如何來使用這Class ..
使用的Code :
private void btnMD5_Click(object sender, RoutedEventArgs e)
{
MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();
byte[] encryptedBytes = md5Provider.ComputeHash(Encoding.UTF8.GetBytes(this.txtInput.Text));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < encryptedBytes.Length; i++)
{
sb.AppendFormat("{0:x2}", encryptedBytes[i]);
}
this.lblMD5.Content = sb.ToString();
}
預覽:
下面我附上…在asp.net 下的Code..
讓您在寫Server 那一端可以配合使用…
public static string md5(string encodetxt)
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = System.Text.Encoding.UTF8.GetBytes(encodetxt);
bs = x.ComputeHash(bs);
System.Text.StringBuilder s = new System.Text.StringBuilder();
foreach (byte b in bs)
{
s.Append(b.ToString("x2").ToLower());
}
return s.ToString();
}
檔案下載..
讚一下:
標籤:
MD5,
Silverlight
|
This entry was posted on 下午4:06
and is filed under
MD5
,
Silverlight
.
You can follow any responses to this entry through
the RSS 2.0 feed.
You can leave a response,
or trackback from your own site.
訂閱:
張貼留言 (Atom)
0 意見:
張貼留言