annotate bindings/as3/ext/com/adobe/crypto/SHA1.as @ 770:c54bc2ffbf92 tip

update tags
author convert-repo
date Fri, 16 Dec 2011 11:34:01 +0000
parents 3a0b9700b3d2
children
rev   line source
mas01mj@732 1 /*
mas01mj@732 2 Copyright (c) 2008, Adobe Systems Incorporated
mas01mj@732 3 All rights reserved.
mas01mj@732 4
mas01mj@732 5 Redistribution and use in source and binary forms, with or without
mas01mj@732 6 modification, are permitted provided that the following conditions are
mas01mj@732 7 met:
mas01mj@732 8
mas01mj@732 9 * Redistributions of source code must retain the above copyright notice,
mas01mj@732 10 this list of conditions and the following disclaimer.
mas01mj@732 11
mas01mj@732 12 * Redistributions in binary form must reproduce the above copyright
mas01mj@732 13 notice, this list of conditions and the following disclaimer in the
mas01mj@732 14 documentation and/or other materials provided with the distribution.
mas01mj@732 15
mas01mj@732 16 * Neither the name of Adobe Systems Incorporated nor the names of its
mas01mj@732 17 contributors may be used to endorse or promote products derived from
mas01mj@732 18 this software without specific prior written permission.
mas01mj@732 19
mas01mj@732 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
mas01mj@732 21 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
mas01mj@732 22 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
mas01mj@732 23 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
mas01mj@732 24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
mas01mj@732 25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
mas01mj@732 26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
mas01mj@732 27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
mas01mj@732 28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
mas01mj@732 29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
mas01mj@732 30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mas01mj@732 31 */
mas01mj@732 32
mas01mj@732 33 package com.adobe.crypto
mas01mj@732 34 {
mas01mj@732 35 import com.adobe.utils.IntUtil;
mas01mj@732 36 import flash.utils.ByteArray;
mas01mj@732 37 import mx.utils.Base64Encoder;
mas01mj@732 38
mas01mj@732 39 /**
mas01mj@732 40 * US Secure Hash Algorithm 1 (SHA1)
mas01mj@732 41 *
mas01mj@732 42 * Implementation based on algorithm description at
mas01mj@732 43 * http://www.faqs.org/rfcs/rfc3174.html
mas01mj@732 44 */
mas01mj@732 45 public class SHA1
mas01mj@732 46 {
mas01mj@732 47 public static var digest:ByteArray;
mas01mj@732 48
mas01mj@732 49 /**
mas01mj@732 50 * Performs the SHA1 hash algorithm on a string.
mas01mj@732 51 *
mas01mj@732 52 * @param s The string to hash
mas01mj@732 53 * @return A string containing the hash value of s
mas01mj@732 54 * @langversion ActionScript 3.0
mas01mj@732 55 * @playerversion 9.0
mas01mj@732 56 * @tiptext
mas01mj@732 57 */
mas01mj@732 58 public static function hash( s:String ):String
mas01mj@732 59 {
mas01mj@732 60 var blocks:Array = createBlocksFromString( s );
mas01mj@732 61 var byteArray:ByteArray = hashBlocks( blocks );
mas01mj@732 62
mas01mj@732 63 return IntUtil.toHex( byteArray.readInt(), true )
mas01mj@732 64 + IntUtil.toHex( byteArray.readInt(), true )
mas01mj@732 65 + IntUtil.toHex( byteArray.readInt(), true )
mas01mj@732 66 + IntUtil.toHex( byteArray.readInt(), true )
mas01mj@732 67 + IntUtil.toHex( byteArray.readInt(), true );
mas01mj@732 68 }
mas01mj@732 69
mas01mj@732 70 /**
mas01mj@732 71 * Performs the SHA1 hash algorithm on a ByteArray.
mas01mj@732 72 *
mas01mj@732 73 * @param data The ByteArray data to hash
mas01mj@732 74 * @return A string containing the hash value of data
mas01mj@732 75 * @langversion ActionScript 3.0
mas01mj@732 76 * @playerversion 9.0
mas01mj@732 77 */
mas01mj@732 78 public static function hashBytes( data:ByteArray ):String
mas01mj@732 79 {
mas01mj@732 80 var blocks:Array = SHA1.createBlocksFromByteArray( data );
mas01mj@732 81 var byteArray:ByteArray = hashBlocks(blocks);
mas01mj@732 82
mas01mj@732 83 return IntUtil.toHex( byteArray.readInt(), true )
mas01mj@732 84 + IntUtil.toHex( byteArray.readInt(), true )
mas01mj@732 85 + IntUtil.toHex( byteArray.readInt(), true )
mas01mj@732 86 + IntUtil.toHex( byteArray.readInt(), true )
mas01mj@732 87 + IntUtil.toHex( byteArray.readInt(), true );
mas01mj@732 88 }
mas01mj@732 89
mas01mj@732 90 /**
mas01mj@732 91 * Performs the SHA1 hash algorithm on a string, then does
mas01mj@732 92 * Base64 encoding on the result.
mas01mj@732 93 *
mas01mj@732 94 * @param s The string to hash
mas01mj@732 95 * @return The base64 encoded hash value of s
mas01mj@732 96 * @langversion ActionScript 3.0
mas01mj@732 97 * @playerversion 9.0
mas01mj@732 98 * @tiptext
mas01mj@732 99 */
mas01mj@732 100 public static function hashToBase64( s:String ):String
mas01mj@732 101 {
mas01mj@732 102 var blocks:Array = SHA1.createBlocksFromString( s );
mas01mj@732 103 var byteArray:ByteArray = hashBlocks(blocks);
mas01mj@732 104
mas01mj@732 105 // ByteArray.toString() returns the contents as a UTF-8 string,
mas01mj@732 106 // which we can't use because certain byte sequences might trigger
mas01mj@732 107 // a UTF-8 conversion. Instead, we convert the bytes to characters
mas01mj@732 108 // one by one.
mas01mj@732 109 var charsInByteArray:String = "";
mas01mj@732 110 byteArray.position = 0;
mas01mj@732 111 for (var j:int = 0; j < byteArray.length; j++)
mas01mj@732 112 {
mas01mj@732 113 var byte:uint = byteArray.readUnsignedByte();
mas01mj@732 114 charsInByteArray += String.fromCharCode(byte);
mas01mj@732 115 }
mas01mj@732 116
mas01mj@732 117 var encoder:Base64Encoder = new Base64Encoder();
mas01mj@732 118 encoder.encode(charsInByteArray);
mas01mj@732 119 return encoder.flush();
mas01mj@732 120 }
mas01mj@732 121
mas01mj@732 122 private static function hashBlocks( blocks:Array ):ByteArray
mas01mj@732 123 {
mas01mj@732 124 // initialize the h's
mas01mj@732 125 var h0:int = 0x67452301;
mas01mj@732 126 var h1:int = 0xefcdab89;
mas01mj@732 127 var h2:int = 0x98badcfe;
mas01mj@732 128 var h3:int = 0x10325476;
mas01mj@732 129 var h4:int = 0xc3d2e1f0;
mas01mj@732 130
mas01mj@732 131 var len:int = blocks.length;
mas01mj@732 132 var w:Array = new Array( 80 );
mas01mj@732 133 var temp:int;
mas01mj@732 134
mas01mj@732 135 // loop over all of the blocks
mas01mj@732 136 for ( var i:int = 0; i < len; i += 16 ) {
mas01mj@732 137
mas01mj@732 138 // 6.1.c
mas01mj@732 139 var a:int = h0;
mas01mj@732 140 var b:int = h1;
mas01mj@732 141 var c:int = h2;
mas01mj@732 142 var d:int = h3;
mas01mj@732 143 var e:int = h4;
mas01mj@732 144
mas01mj@732 145 // 80 steps to process each block
mas01mj@732 146 var t:int;
mas01mj@732 147 for ( t = 0; t < 20; t++ ) {
mas01mj@732 148
mas01mj@732 149 if ( t < 16 ) {
mas01mj@732 150 // 6.1.a
mas01mj@732 151 w[ t ] = blocks[ i + t ];
mas01mj@732 152 } else {
mas01mj@732 153 // 6.1.b
mas01mj@732 154 temp = w[ t - 3 ] ^ w[ t - 8 ] ^ w[ t - 14 ] ^ w[ t - 16 ];
mas01mj@732 155 w[ t ] = ( temp << 1 ) | ( temp >>> 31 )
mas01mj@732 156 }
mas01mj@732 157
mas01mj@732 158 // 6.1.d
mas01mj@732 159 temp = ( ( a << 5 ) | ( a >>> 27 ) ) + ( ( b & c ) | ( ~b & d ) ) + e + int( w[ t ] ) + 0x5a827999;
mas01mj@732 160
mas01mj@732 161 e = d;
mas01mj@732 162 d = c;
mas01mj@732 163 c = ( b << 30 ) | ( b >>> 2 );
mas01mj@732 164 b = a;
mas01mj@732 165 a = temp;
mas01mj@732 166 }
mas01mj@732 167 for ( ; t < 40; t++ )
mas01mj@732 168 {
mas01mj@732 169 // 6.1.b
mas01mj@732 170 temp = w[ t - 3 ] ^ w[ t - 8 ] ^ w[ t - 14 ] ^ w[ t - 16 ];
mas01mj@732 171 w[ t ] = ( temp << 1 ) | ( temp >>> 31 )
mas01mj@732 172
mas01mj@732 173 // 6.1.d
mas01mj@732 174 temp = ( ( a << 5 ) | ( a >>> 27 ) ) + ( b ^ c ^ d ) + e + int( w[ t ] ) + 0x6ed9eba1;
mas01mj@732 175
mas01mj@732 176 e = d;
mas01mj@732 177 d = c;
mas01mj@732 178 c = ( b << 30 ) | ( b >>> 2 );
mas01mj@732 179 b = a;
mas01mj@732 180 a = temp;
mas01mj@732 181 }
mas01mj@732 182 for ( ; t < 60; t++ )
mas01mj@732 183 {
mas01mj@732 184 // 6.1.b
mas01mj@732 185 temp = w[ t - 3 ] ^ w[ t - 8 ] ^ w[ t - 14 ] ^ w[ t - 16 ];
mas01mj@732 186 w[ t ] = ( temp << 1 ) | ( temp >>> 31 )
mas01mj@732 187
mas01mj@732 188 // 6.1.d
mas01mj@732 189 temp = ( ( a << 5 ) | ( a >>> 27 ) ) + ( ( b & c ) | ( b & d ) | ( c & d ) ) + e + int( w[ t ] ) + 0x8f1bbcdc;
mas01mj@732 190
mas01mj@732 191 e = d;
mas01mj@732 192 d = c;
mas01mj@732 193 c = ( b << 30 ) | ( b >>> 2 );
mas01mj@732 194 b = a;
mas01mj@732 195 a = temp;
mas01mj@732 196 }
mas01mj@732 197 for ( ; t < 80; t++ )
mas01mj@732 198 {
mas01mj@732 199 // 6.1.b
mas01mj@732 200 temp = w[ t - 3 ] ^ w[ t - 8 ] ^ w[ t - 14 ] ^ w[ t - 16 ];
mas01mj@732 201 w[ t ] = ( temp << 1 ) | ( temp >>> 31 )
mas01mj@732 202
mas01mj@732 203 // 6.1.d
mas01mj@732 204 temp = ( ( a << 5 ) | ( a >>> 27 ) ) + ( b ^ c ^ d ) + e + int( w[ t ] ) + 0xca62c1d6;
mas01mj@732 205
mas01mj@732 206 e = d;
mas01mj@732 207 d = c;
mas01mj@732 208 c = ( b << 30 ) | ( b >>> 2 );
mas01mj@732 209 b = a;
mas01mj@732 210 a = temp;
mas01mj@732 211 }
mas01mj@732 212
mas01mj@732 213 // 6.1.e
mas01mj@732 214 h0 += a;
mas01mj@732 215 h1 += b;
mas01mj@732 216 h2 += c;
mas01mj@732 217 h3 += d;
mas01mj@732 218 h4 += e;
mas01mj@732 219 }
mas01mj@732 220
mas01mj@732 221 var byteArray:ByteArray = new ByteArray();
mas01mj@732 222 byteArray.writeInt(h0);
mas01mj@732 223 byteArray.writeInt(h1);
mas01mj@732 224 byteArray.writeInt(h2);
mas01mj@732 225 byteArray.writeInt(h3);
mas01mj@732 226 byteArray.writeInt(h4);
mas01mj@732 227 byteArray.position = 0;
mas01mj@732 228
mas01mj@732 229 digest = new ByteArray();
mas01mj@732 230 digest.writeBytes(byteArray);
mas01mj@732 231 digest.position = 0;
mas01mj@732 232 return byteArray;
mas01mj@732 233 }
mas01mj@732 234
mas01mj@732 235 /**
mas01mj@732 236 * Converts a ByteArray to a sequence of 16-word blocks
mas01mj@732 237 * that we'll do the processing on. Appends padding
mas01mj@732 238 * and length in the process.
mas01mj@732 239 *
mas01mj@732 240 * @param data The data to split into blocks
mas01mj@732 241 * @return An array containing the blocks into which data was split
mas01mj@732 242 */
mas01mj@732 243 private static function createBlocksFromByteArray( data:ByteArray ):Array
mas01mj@732 244 {
mas01mj@732 245 var oldPosition:int = data.position;
mas01mj@732 246 data.position = 0;
mas01mj@732 247
mas01mj@732 248 var blocks:Array = new Array();
mas01mj@732 249 var len:int = data.length * 8;
mas01mj@732 250 var mask:int = 0xFF; // ignore hi byte of characters > 0xFF
mas01mj@732 251 for( var i:int = 0; i < len; i += 8 )
mas01mj@732 252 {
mas01mj@732 253 blocks[ i >> 5 ] |= ( data.readByte() & mask ) << ( 24 - i % 32 );
mas01mj@732 254 }
mas01mj@732 255
mas01mj@732 256 // append padding and length
mas01mj@732 257 blocks[ len >> 5 ] |= 0x80 << ( 24 - len % 32 );
mas01mj@732 258 blocks[ ( ( ( len + 64 ) >> 9 ) << 4 ) + 15 ] = len;
mas01mj@732 259
mas01mj@732 260 data.position = oldPosition;
mas01mj@732 261
mas01mj@732 262 return blocks;
mas01mj@732 263 }
mas01mj@732 264
mas01mj@732 265 /**
mas01mj@732 266 * Converts a string to a sequence of 16-word blocks
mas01mj@732 267 * that we'll do the processing on. Appends padding
mas01mj@732 268 * and length in the process.
mas01mj@732 269 *
mas01mj@732 270 * @param s The string to split into blocks
mas01mj@732 271 * @return An array containing the blocks that s was split into.
mas01mj@732 272 */
mas01mj@732 273 private static function createBlocksFromString( s:String ):Array
mas01mj@732 274 {
mas01mj@732 275 var blocks:Array = new Array();
mas01mj@732 276 var len:int = s.length * 8;
mas01mj@732 277 var mask:int = 0xFF; // ignore hi byte of characters > 0xFF
mas01mj@732 278 for( var i:int = 0; i < len; i += 8 ) {
mas01mj@732 279 blocks[ i >> 5 ] |= ( s.charCodeAt( i / 8 ) & mask ) << ( 24 - i % 32 );
mas01mj@732 280 }
mas01mj@732 281
mas01mj@732 282 // append padding and length
mas01mj@732 283 blocks[ len >> 5 ] |= 0x80 << ( 24 - len % 32 );
mas01mj@732 284 blocks[ ( ( ( len + 64 ) >> 9 ) << 4 ) + 15 ] = len;
mas01mj@732 285 return blocks;
mas01mj@732 286 }
mas01mj@732 287
mas01mj@732 288 }
mas01mj@732 289 }