source: code/Website/open-flash-chart/com/adobe/crypto/SHA256.as@ 7849

Last change on this file since 7849 was 7849, checked in by dennisw, 15 years ago
File size: 8.9 KB
Line 
1/*
2Adobe Systems Incorporated(r) Source Code License Agreement
3Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
4
5Please read this Source Code License Agreement carefully before using
6the source code.
7
8Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
9no-charge, royalty-free, irrevocable copyright license, to reproduce,
10prepare derivative works of, publicly display, publicly perform, and
11distribute this source code and such derivative works in source or
12object code form without any attribution requirements.
13
14The name "Adobe Systems Incorporated" must not be used to endorse or promote products
15derived from the source code without prior written permission.
16
17You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
18against any loss, damage, claims or lawsuits, including attorney's
19fees that arise or result from your use or distribution of the source
20code.
21
22THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
23ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
24BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
26NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
27OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
30OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
33ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36package com.adobe.crypto
37{
38 import com.adobe.utils.IntUtil;
39 import flash.utils.ByteArray;
40 import mx.utils.Base64Encoder;
41
42 /**
43 * The SHA-256 algorithm
44 *
45 * @see http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
46 */
47 public class SHA256
48 {
49
50 /**
51 * Performs the SHA256 hash algorithm on a string.
52 *
53 * @param s The string to hash
54 * @return A string containing the hash value of s
55 * @langversion ActionScript 3.0
56 * @playerversion 9.0
57 * @tiptext
58 */
59 public static function hash( s:String ):String {
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 + IntUtil.toHex( byteArray.readInt(), true )
69 + IntUtil.toHex( byteArray.readInt(), true )
70 + IntUtil.toHex( byteArray.readInt(), true );
71 }
72
73 /**
74 * Performs the SHA256 hash algorithm on a ByteArray.
75 *
76 * @param data The ByteArray data to hash
77 * @return A string containing the hash value of data
78 * @langversion ActionScript 3.0
79 * @playerversion 9.0
80 */
81 public static function hashBytes( data:ByteArray ):String
82 {
83 var blocks:Array = createBlocksFromByteArray( data );
84 var byteArray:ByteArray = hashBlocks(blocks);
85
86 return IntUtil.toHex( byteArray.readInt(), true )
87 + IntUtil.toHex( byteArray.readInt(), true )
88 + IntUtil.toHex( byteArray.readInt(), true )
89 + IntUtil.toHex( byteArray.readInt(), true )
90 + IntUtil.toHex( byteArray.readInt(), true )
91 + IntUtil.toHex( byteArray.readInt(), true )
92 + IntUtil.toHex( byteArray.readInt(), true )
93 + IntUtil.toHex( byteArray.readInt(), true );
94 }
95
96 /**
97 * Performs the SHA256 hash algorithm on a string, then does
98 * Base64 encoding on the result.
99 *
100 * @param s The string to hash
101 * @return The base64 encoded hash value of s
102 * @langversion ActionScript 3.0
103 * @playerversion 9.0
104 * @tiptext
105 */
106 public static function hashToBase64( s:String ):String
107 {
108 var blocks:Array = createBlocksFromString( s );
109 var byteArray:ByteArray = hashBlocks(blocks);
110
111 // ByteArray.toString() returns the contents as a UTF-8 string,
112 // which we can't use because certain byte sequences might trigger
113 // a UTF-8 conversion. Instead, we convert the bytes to characters
114 // one by one.
115 var charsInByteArray:String = "";
116 byteArray.position = 0;
117 for (var j:int = 0; j < byteArray.length; j++)
118 {
119 var byte:uint = byteArray.readUnsignedByte();
120 charsInByteArray += String.fromCharCode(byte);
121 }
122
123 var encoder:Base64Encoder = new Base64Encoder();
124 encoder.encode(charsInByteArray);
125 return encoder.flush();
126 }
127
128 private static function hashBlocks( blocks:Array ):ByteArray {
129 var h0:int = 0x6a09e667;
130 var h1:int = 0xbb67ae85;
131 var h2:int = 0x3c6ef372;
132 var h3:int = 0xa54ff53a;
133 var h4:int = 0x510e527f;
134 var h5:int = 0x9b05688c;
135 var h6:int = 0x1f83d9ab;
136 var h7:int = 0x5be0cd19;
137
138 var k:Array = new Array(0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2);
139
140 var len:int = blocks.length;
141 var w:Array = new Array( 64 );
142
143 // loop over all of the blocks
144 for ( var i:int = 0; i < len; i += 16 ) {
145
146 var a:int = h0;
147 var b:int = h1;
148 var c:int = h2;
149 var d:int = h3;
150 var e:int = h4;
151 var f:int = h5;
152 var g:int = h6;
153 var h:int = h7;
154
155 for(var t:int = 0; t < 64; t++) {
156
157 if ( t < 16 ) {
158 w[t] = blocks[ i + t ];
159 if(isNaN(w[t])) { w[t] = 0; }
160 } else {
161 var ws0:int = IntUtil.ror(w[t-15], 7) ^ IntUtil.ror(w[t-15], 18) ^ (w[t-15] >>> 3);
162 var ws1:int = IntUtil.ror(w[t-2], 17) ^ IntUtil.ror(w[t-2], 19) ^ (w[t-2] >>> 10);
163 w[t] = w[t-16] + ws0 + w[t-7] + ws1;
164 }
165
166 var s0:int = IntUtil.ror(a, 2) ^ IntUtil.ror(a, 13) ^ IntUtil.ror(a, 22);
167 var maj:int = (a & b) ^ (a & c) ^ (b & c);
168 var t2:int = s0 + maj;
169 var s1:int = IntUtil.ror(e, 6) ^ IntUtil.ror(e, 11) ^ IntUtil.ror(e, 25);
170 var ch:int = (e & f) ^ ((~e) & g);
171 var t1:int = h + s1 + ch + k[t] + w[t];
172
173 h = g;
174 g = f;
175 f = e;
176 e = d + t1;
177 d = c;
178 c = b;
179 b = a;
180 a = t1 + t2;
181 }
182
183 //Add this chunk's hash to result so far:
184 h0 += a;
185 h1 += b;
186 h2 += c;
187 h3 += d;
188 h4 += e;
189 h5 += f;
190 h6 += g;
191 h7 += h;
192 }
193
194 var byteArray:ByteArray = new ByteArray();
195 byteArray.writeInt(h0);
196 byteArray.writeInt(h1);
197 byteArray.writeInt(h2);
198 byteArray.writeInt(h3);
199 byteArray.writeInt(h4);
200 byteArray.writeInt(h5);
201 byteArray.writeInt(h6);
202 byteArray.writeInt(h7);
203 byteArray.position = 0;
204 return byteArray;
205 }
206
207 /**
208 * Converts a ByteArray to a sequence of 16-word blocks
209 * that we'll do the processing on. Appends padding
210 * and length in the process.
211 *
212 * @param data The data to split into blocks
213 * @return An array containing the blocks into which data was split
214 */
215 private static function createBlocksFromByteArray( data:ByteArray ):Array
216 {
217 var oldPosition:int = data.position;
218 data.position = 0;
219
220 var blocks:Array = new Array();
221 var len:int = data.length * 8;
222 var mask:int = 0xFF; // ignore hi byte of characters > 0xFF
223 for( var i:int = 0; i < len; i += 8 )
224 {
225 blocks[ i >> 5 ] |= ( data.readByte() & mask ) << ( 24 - i % 32 );
226 }
227
228 // append padding and length
229 blocks[ len >> 5 ] |= 0x80 << ( 24 - len % 32 );
230 blocks[ ( ( ( len + 64 ) >> 9 ) << 4 ) + 15 ] = len;
231
232 data.position = oldPosition;
233
234 return blocks;
235 }
236
237 /**
238 * Converts a string to a sequence of 16-word blocks
239 * that we'll do the processing on. Appends padding
240 * and length in the process.
241 *
242 * @param s The string to split into blocks
243 * @return An array containing the blocks that s was split into.
244 */
245 private static function createBlocksFromString( s:String ):Array
246 {
247 var blocks:Array = new Array();
248 var len:int = s.length * 8;
249 var mask:int = 0xFF; // ignore hi byte of characters > 0xFF
250 for( var i:int = 0; i < len; i += 8 ) {
251 blocks[ i >> 5 ] |= ( s.charCodeAt( i / 8 ) & mask ) << ( 24 - i % 32 );
252 }
253
254 // append padding and length
255 blocks[ len >> 5 ] |= 0x80 << ( 24 - len % 32 );
256 blocks[ ( ( ( len + 64 ) >> 9 ) << 4 ) + 15 ] = len;
257 return blocks;
258 }
259 }
260}
Note: See TracBrowser for help on using the repository browser.