Path: blob/trunk/third_party/closure/goog/crypt/hmac.js
2868 views
// Copyright 2011 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Implementation of HMAC in JavaScript.16*17* Usage:18* var hmac = new goog.crypt.Hmac(new goog.crypt.sha1(), key, 64);19* var digest = hmac.getHmac(bytes);20*21* @author [email protected] (Jige Yu) - port to closure22*/232425goog.provide('goog.crypt.Hmac');2627goog.require('goog.crypt.Hash');28293031/**32* @constructor33* @param {!goog.crypt.Hash} hasher An object to serve as a hash function.34* @param {Array<number>} key The secret key to use to calculate the hmac.35* Should be an array of not more than {@code blockSize} integers in36{0, 255}.37* @param {number=} opt_blockSize Optional. The block size {@code hasher} uses.38* If not specified, uses the block size from the hasher, or 16 if it is39* not specified.40* @extends {goog.crypt.Hash}41* @final42* @struct43*/44goog.crypt.Hmac = function(hasher, key, opt_blockSize) {45goog.crypt.Hmac.base(this, 'constructor');4647/**48* The underlying hasher to calculate hash.49*50* @type {!goog.crypt.Hash}51* @private52*/53this.hasher_ = hasher;5455this.blockSize = opt_blockSize || hasher.blockSize || 16;5657/**58* The outer padding array of hmac59*60* @type {!Array<number>}61* @private62*/63this.keyO_ = new Array(this.blockSize);6465/**66* The inner padding array of hmac67*68* @type {!Array<number>}69* @private70*/71this.keyI_ = new Array(this.blockSize);7273this.initialize_(key);74};75goog.inherits(goog.crypt.Hmac, goog.crypt.Hash);767778/**79* Outer padding byte of HMAC algorith, per http://en.wikipedia.org/wiki/HMAC80*81* @type {number}82* @private83*/84goog.crypt.Hmac.OPAD_ = 0x5c;858687/**88* Inner padding byte of HMAC algorith, per http://en.wikipedia.org/wiki/HMAC89*90* @type {number}91* @private92*/93goog.crypt.Hmac.IPAD_ = 0x36;949596/**97* Initializes Hmac by precalculating the inner and outer paddings.98*99* @param {Array<number>} key The secret key to use to calculate the hmac.100* Should be an array of not more than {@code blockSize} integers in101{0, 255}.102* @private103*/104goog.crypt.Hmac.prototype.initialize_ = function(key) {105if (key.length > this.blockSize) {106this.hasher_.update(key);107key = this.hasher_.digest();108this.hasher_.reset();109}110// Precalculate padded and xor'd keys.111var keyByte;112for (var i = 0; i < this.blockSize; i++) {113if (i < key.length) {114keyByte = key[i];115} else {116keyByte = 0;117}118this.keyO_[i] = keyByte ^ goog.crypt.Hmac.OPAD_;119this.keyI_[i] = keyByte ^ goog.crypt.Hmac.IPAD_;120}121// Be ready for an immediate update.122this.hasher_.update(this.keyI_);123};124125126/** @override */127goog.crypt.Hmac.prototype.reset = function() {128this.hasher_.reset();129this.hasher_.update(this.keyI_);130};131132133/** @override */134goog.crypt.Hmac.prototype.update = function(bytes, opt_length) {135this.hasher_.update(bytes, opt_length);136};137138139/** @override */140goog.crypt.Hmac.prototype.digest = function() {141var temp = this.hasher_.digest();142this.hasher_.reset();143this.hasher_.update(this.keyO_);144this.hasher_.update(temp);145return this.hasher_.digest();146};147148149/**150* Calculates an HMAC for a given message.151*152* @param {Array<number>|Uint8Array|string} message Data to Hmac.153* @return {!Array<number>} the digest of the given message.154*/155goog.crypt.Hmac.prototype.getHmac = function(message) {156this.reset();157this.update(message);158return this.digest();159};160161162