Project

General

Profile

Statistics
| Branch: | Revision:

root / docs / www / colonyscout / internal / includes / uploadify / com / adobe / crypto / SHA1.as @ f59acf11

History | View | Annotate | Download (7.87 KB)

1
/*
2
  Copyright (c) 2008, Adobe Systems Incorporated
3
  All rights reserved.
4

    
5
  Redistribution and use in source and binary forms, with or without 
6
  modification, are permitted provided that the following conditions are
7
  met:
8

    
9
  * Redistributions of source code must retain the above copyright notice, 
10
    this list of conditions and the following disclaimer.
11
  
12
  * Redistributions in binary form must reproduce the above copyright
13
    notice, this list of conditions and the following disclaimer in the 
14
    documentation and/or other materials provided with the distribution.
15
  
16
  * Neither the name of Adobe Systems Incorporated nor the names of its 
17
    contributors may be used to endorse or promote products derived from 
18
    this software without specific prior written permission.
19

    
20
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21
  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
24
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32

    
33
package com.adobe.crypto
34
{
35
	import com.adobe.utils.IntUtil;
36
	import flash.utils.ByteArray;
37
	import mx.utils.Base64Encoder;
38
	
39
	/**
40
	 *  US Secure Hash Algorithm 1 (SHA1)
41
	 *
42
	 *  Implementation based on algorithm description at 
43
	 *  http://www.faqs.org/rfcs/rfc3174.html
44
	 */
45
	public class SHA1
46
	{
47
		public static var digest:ByteArray;
48
		
49
		/**
50
		 *  Performs the SHA1 hash algorithm on a string.
51
		 *
52
		 *  @param s		The string to hash
53
		 *  @return			A string containing the hash value of s
54
		 *  @langversion	ActionScript 3.0
55
		 *  @playerversion	9.0
56
		 *  @tiptext
57
		 */
58
		public static function hash( s:String ):String
59
		{
60
			var blocks:Array = createBlocksFromString( s );
61
			var byteArray:ByteArray = hashBlocks( blocks );
62
			
63
			return IntUtil.toHex( byteArray.readInt(), true )
64
					+ IntUtil.toHex( byteArray.readInt(), true )
65
					+ IntUtil.toHex( byteArray.readInt(), true )
66
					+ IntUtil.toHex( byteArray.readInt(), true )
67
					+ IntUtil.toHex( byteArray.readInt(), true );
68
		}
69
		
70
		/**
71
		 *  Performs the SHA1 hash algorithm on a ByteArray.
72
		 *
73
		 *  @param data		The ByteArray data to hash
74
		 *  @return			A string containing the hash value of data
75
		 *  @langversion	ActionScript 3.0
76
		 *  @playerversion	9.0
77
		 */
78
		public static function hashBytes( data:ByteArray ):String
79
		{
80
			var blocks:Array = SHA1.createBlocksFromByteArray( data );
81
			var byteArray:ByteArray = hashBlocks(blocks);
82
			
83
			return IntUtil.toHex( byteArray.readInt(), true )
84
					+ IntUtil.toHex( byteArray.readInt(), true )
85
					+ IntUtil.toHex( byteArray.readInt(), true )
86
					+ IntUtil.toHex( byteArray.readInt(), true )
87
					+ IntUtil.toHex( byteArray.readInt(), true );
88
		}
89
		
90
		/**
91
		 *  Performs the SHA1 hash algorithm on a string, then does
92
		 *  Base64 encoding on the result.
93
		 *
94
		 *  @param s		The string to hash
95
		 *  @return			The base64 encoded hash value of s
96
		 *  @langversion	ActionScript 3.0
97
		 *  @playerversion	9.0
98
		 *  @tiptext
99
		 */
100
		public static function hashToBase64( s:String ):String
101
		{
102
			var blocks:Array = SHA1.createBlocksFromString( s );
103
			var byteArray:ByteArray = hashBlocks(blocks);
104

    
105
			// ByteArray.toString() returns the contents as a UTF-8 string,
106
			// which we can't use because certain byte sequences might trigger
107
			// a UTF-8 conversion.  Instead, we convert the bytes to characters
108
			// one by one.
109
			var charsInByteArray:String = "";
110
			byteArray.position = 0;
111
			for (var j:int = 0; j < byteArray.length; j++)
112
			{
113
				var byte:uint = byteArray.readUnsignedByte();
114
				charsInByteArray += String.fromCharCode(byte);
115
			}
116

    
117
			var encoder:Base64Encoder = new Base64Encoder();
118
			encoder.encode(charsInByteArray);
119
			return encoder.flush();
120
		}
121
		
122
		private static function hashBlocks( blocks:Array ):ByteArray
123
		{
124
			// initialize the h's
125
			var h0:int = 0x67452301;
126
			var h1:int = 0xefcdab89;
127
			var h2:int = 0x98badcfe;
128
			var h3:int = 0x10325476;
129
			var h4:int = 0xc3d2e1f0;
130
			
131
			var len:int = blocks.length;
132
			var w:Array = new Array( 80 );
133
			
134
			// loop over all of the blocks
135
			for ( var i:int = 0; i < len; i += 16 ) {
136
			
137
				// 6.1.c
138
				var a:int = h0;
139
				var b:int = h1;
140
				var c:int = h2;
141
				var d:int = h3;
142
				var e:int = h4;
143
				
144
				// 80 steps to process each block
145
				// TODO: unroll for faster execution, or 4 loops of
146
				// 20 each to avoid the k and f function calls
147
				for ( var t:int = 0; t < 80; t++ ) {
148
					
149
					if ( t < 16 ) {
150
						// 6.1.a
151
						w[ t ] = blocks[ i + t ];
152
					} else {
153
						// 6.1.b
154
						w[ t ] = IntUtil.rol( w[ t - 3 ] ^ w[ t - 8 ] ^ w[ t - 14 ] ^ w[ t - 16 ], 1 );
155
					}
156
					
157
					// 6.1.d
158
					var temp:int = IntUtil.rol( a, 5 ) + f( t, b, c, d ) + e + int( w[ t ] ) + k( t );
159
					
160
					e = d;
161
					d = c;
162
					c = IntUtil.rol( b, 30 );
163
					b = a;
164
					a = temp;
165
				}
166
				
167
				// 6.1.e
168
				h0 += a;
169
				h1 += b;
170
				h2 += c;
171
				h3 += d;
172
				h4 += e;		
173
			}
174
			
175
			var byteArray:ByteArray = new ByteArray();
176
			byteArray.writeInt(h0);
177
			byteArray.writeInt(h1);
178
			byteArray.writeInt(h2);
179
			byteArray.writeInt(h3);
180
			byteArray.writeInt(h4);
181
			byteArray.position = 0;
182
			
183
			digest = new ByteArray();
184
			digest.writeBytes(byteArray);
185
			digest.position = 0;
186
			return byteArray;
187
		}
188

    
189
		/**
190
		 *  Performs the logical function based on t
191
		 */
192
		private static function f( t:int, b:int, c:int, d:int ):int {
193
			if ( t < 20 ) {
194
				return ( b & c ) | ( ~b & d );
195
			} else if ( t < 40 ) {
196
				return b ^ c ^ d;
197
			} else if ( t < 60 ) {
198
				return ( b & c ) | ( b & d ) | ( c & d );
199
			}
200
			return b ^ c ^ d;
201
		}
202
		
203
		/**
204
		 *  Determines the constant value based on t
205
		 */
206
		private static function k( t:int ):int {
207
			if ( t < 20 ) {
208
				return 0x5a827999;
209
			} else if ( t < 40 ) {
210
				return 0x6ed9eba1;
211
			} else if ( t < 60 ) {
212
				return 0x8f1bbcdc;
213
			}
214
			return 0xca62c1d6;
215
		}
216
					
217
		/**
218
		 *  Converts a ByteArray to a sequence of 16-word blocks
219
		 *  that we'll do the processing on.  Appends padding
220
		 *  and length in the process.
221
		 *
222
		 *  @param data		The data to split into blocks
223
		 *  @return			An array containing the blocks into which data was split
224
		 */
225
		private static function createBlocksFromByteArray( data:ByteArray ):Array
226
		{
227
			var oldPosition:int = data.position;
228
			data.position = 0;
229
			
230
			var blocks:Array = new Array();
231
			var len:int = data.length * 8;
232
			var mask:int = 0xFF; // ignore hi byte of characters > 0xFF
233
			for( var i:int = 0; i < len; i += 8 )
234
			{
235
				blocks[ i >> 5 ] |= ( data.readByte() & mask ) << ( 24 - i % 32 );
236
			}
237
			
238
			// append padding and length
239
			blocks[ len >> 5 ] |= 0x80 << ( 24 - len % 32 );
240
			blocks[ ( ( ( len + 64 ) >> 9 ) << 4 ) + 15 ] = len;
241
			
242
			data.position = oldPosition;
243
			
244
			return blocks;
245
		}
246
					
247
		/**
248
		 *  Converts a string to a sequence of 16-word blocks
249
		 *  that we'll do the processing on.  Appends padding
250
		 *  and length in the process.
251
		 *
252
		 *  @param s	The string to split into blocks
253
		 *  @return		An array containing the blocks that s was split into.
254
		 */
255
		private static function createBlocksFromString( s:String ):Array
256
		{
257
			var blocks:Array = new Array();
258
			var len:int = s.length * 8;
259
			var mask:int = 0xFF; // ignore hi byte of characters > 0xFF
260
			for( var i:int = 0; i < len; i += 8 ) {
261
				blocks[ i >> 5 ] |= ( s.charCodeAt( i / 8 ) & mask ) << ( 24 - i % 32 );
262
			}
263
			
264
			// append padding and length
265
			blocks[ len >> 5 ] |= 0x80 << ( 24 - len % 32 );
266
			blocks[ ( ( ( len + 64 ) >> 9 ) << 4 ) + 15 ] = len;
267
			return blocks;
268
		}
269
		
270
	}
271
}