+/*\r
+ Copyright (c) 2008, Adobe Systems Incorporated\r
+ All rights reserved.\r
+\r
+ Redistribution and use in source and binary forms, with or without \r
+ modification, are permitted provided that the following conditions are\r
+ met:\r
+\r
+ * Redistributions of source code must retain the above copyright notice, \r
+ this list of conditions and the following disclaimer.\r
+ \r
+ * Redistributions in binary form must reproduce the above copyright\r
+ notice, this list of conditions and the following disclaimer in the \r
+ documentation and/or other materials provided with the distribution.\r
+ \r
+ * Neither the name of Adobe Systems Incorporated nor the names of its \r
+ contributors may be used to endorse or promote products derived from \r
+ this software without specific prior written permission.\r
+\r
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS\r
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+package com.adobe.crypto {\r
+ import flash.utils.ByteArray;\r
+ import flash.utils.Endian;\r
+ import flash.utils.describeType;\r
+ /**\r
+ * Keyed-Hashing for Message Authentication\r
+ * Implementation based on algorithm description at \r
+ * http://www.faqs.org/rfcs/rfc2104.html\r
+ */\r
+ public class HMAC \r
+ {\r
+ /**\r
+ * Performs the HMAC hash algorithm using byte arrays.\r
+ *\r
+ * @param secret The secret key\r
+ * @param message The message to hash\r
+ * @param algorithm Hash object to use\r
+ * @return A string containing the hash value of message\r
+ * @langversion ActionScript 3.0\r
+ * @playerversion Flash 8.5\r
+ * @tiptext\r
+ */\r
+ public static function hash( secret:String, message:String, algorithm:Object = null ):String\r
+ {\r
+ var text:ByteArray = new ByteArray();\r
+ var k_secret:ByteArray = new ByteArray();\r
+ \r
+ text.writeUTFBytes(message);\r
+ k_secret.writeUTFBytes(secret);\r
+ \r
+ return hashBytes(k_secret, text, algorithm);\r
+ }\r
+ \r
+ /**\r
+ * Performs the HMAC hash algorithm using string.\r
+ *\r
+ * @param secret The secret key\r
+ * @param message The message to hash\r
+ * @param algorithm Hash object to use\r
+ * @return A string containing the hash value of message\r
+ * @langversion ActionScript 3.0\r
+ * @playerversion Flash 8.5\r
+ * @tiptext\r
+ */\r
+ public static function hashBytes( secret:ByteArray, message:ByteArray, algorithm:Object = null ):String\r
+ {\r
+ var ipad:ByteArray = new ByteArray();\r
+ var opad:ByteArray = new ByteArray();\r
+ var endian:String = Endian.BIG_ENDIAN;\r
+ \r
+ if(algorithm == null){\r
+ algorithm = MD5;\r
+ }\r
+ \r
+ if ( describeType(algorithm).@name.toString() == "com.adobe.crypto::MD5" ) {\r
+ endian = Endian.LITTLE_ENDIAN;\r
+ }\r
+ \r
+ if ( secret.length > 64 ) {\r
+ algorithm.hashBytes(secret);\r
+ secret = new ByteArray();\r
+ secret.endian = endian;\r
+ \r
+ while ( algorithm.digest.bytesAvailable != 0 ) {\r
+ secret.writeInt(algorithm.digest.readInt());\r
+ }\r
+ }\r
+\r
+ secret.length = 64\r
+ secret.position = 0;\r
+ for ( var x:int = 0; x < 64; x++ ) {\r
+ var byte:int = secret.readByte();\r
+ ipad.writeByte(0x36 ^ byte);\r
+ opad.writeByte(0x5c ^ byte);\r
+ }\r
+ \r
+ ipad.writeBytes(message);\r
+ algorithm.hashBytes(ipad);\r
+ var tmp:ByteArray = new ByteArray();\r
+ tmp.endian = endian; \r
+ \r
+ while ( algorithm.digest.bytesAvailable != 0 ) {\r
+ tmp.writeInt(algorithm.digest.readInt());\r
+ }\r
+ tmp.position = 0;\r
+ \r
+ while ( tmp.bytesAvailable != 0 ) {\r
+ opad.writeByte(tmp.readUnsignedByte());\r
+ }\r
+ return algorithm.hashBytes( opad );\r
+ }\r
+ \r
+ }\r
+ \r
+}\r