PageRenderTime 2ms CodeModel.GetById 2ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/js/yii/base/CSecurityManager.js

http://github.com/phpnode/YiiJS
JavaScript | 246 lines | 129 code | 4 blank | 113 comment | 22 complexity | ae3f039d0d9bd496723740f5623cafbb MD5 | raw file
  1/*global Yii, php, sjcl, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
  2/**
  3 * CSecurityManager provides private keys, hashing and encryption functions.
  4 * 
  5 * CSecurityManager is used by Yii components and applications for security-related purpose.
  6 * For example, it is used in cookie validation feature to prevent cookie data
  7 * from being tampered.
  8 * 
  9 * CSecurityManager is mainly used to protect data from being tampered and viewed.
 10 * It can generate HMAC and encrypt the data. The private key used to generate HMAC
 11 * is set by {@link setValidationKey ValidationKey}. The key used to encrypt data is
 12 * specified by {@link setEncryptionKey EncryptionKey}. If the above keys are not
 13 * explicitly set, random keys will be generated and used.
 14 * 
 15 * To protected data with HMAC, call {@link hashData()}; and to check if the data
 16 * is tampered, call {@link validateData()}, which will return the real data if
 17 * it is not tampered. The algorithm used to generated HMAC is specified by
 18 * {@link validation}.
 19 * 
 20 * To encrypt and decrypt data, call {@link encrypt()} and {@link decrypt()}
 21 * respectively, which uses 3DES encryption algorithm.  Note, the PHP Mcrypt
 22 * extension must be installed and loaded.
 23 * 
 24 * CSecurityManager is a core application component that can be accessed via
 25 * {@link CApplication::getSecurityManager()}.
 26 * 
 27 * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
 28 * @version $Id: CSecurityManager.php 3001 2011-02-24 16:42:44Z alexander.makarow $
 29 * @package system.base
 30 * @since 1.0
 31 * @author Charles Pick
 32 * @class
 33 * @extends Yii.CApplicationComponent
 34 */
 35Yii.CSecurityManager = function CSecurityManager() {
 36};
 37Yii.CSecurityManager.prototype = new Yii.CApplicationComponent();
 38Yii.CSecurityManager.prototype.constructor =  Yii.CSecurityManager;
 39/**
 40 * @const
 41 */
 42Yii.CSecurityManager.STATE_VALIDATION_KEY = 'Yii.CSecurityManager.validationkey';
 43/**
 44 * @const
 45 */
 46Yii.CSecurityManager.STATE_ENCRYPTION_KEY = 'Yii.CSecurityManager.encryptionkey';
 47/**
 48 * @var {String} the name of the hashing algorithm to be used by {@link computeHMAC}.
 49 * 
 50 * Defaults to 'sha1', meaning using SHA1 hash algorithm.
 51 * @since 1.1.3
 52 */
 53Yii.CSecurityManager.prototype.hashAlgorithm = 'sha1';
 54
 55Yii.CSecurityManager.prototype._validationKey = null;
 56Yii.CSecurityManager.prototype._encryptionKey = null;
 57/**
 58 * @returns {String} a randomly generated private key
 59 */
 60Yii.CSecurityManager.prototype.generateRandomKey = function () {
 61		return php.sprintf('%08x%08x%08x%08x',php.mt_rand(),php.mt_rand(),php.mt_rand(),php.mt_rand());
 62	};
 63/**
 64 * @returns {String} the private key used to generate HMAC.
 65 * If the key is not explicitly set, a random one is generated and returned.
 66 */
 67Yii.CSecurityManager.prototype.getValidationKey = function () {
 68		var key;
 69		if(this._validationKey!==null) {
 70			return this._validationKey;
 71		}
 72		else {
 73			if((key=Yii.app().getGlobalState(this.STATE_VALIDATION_KEY))!==null) {
 74				this.setValidationKey(key);
 75			}
 76			else {
 77				key=this.generateRandomKey();
 78				this.setValidationKey(key);
 79				Yii.app().setGlobalState(this.STATE_VALIDATION_KEY,key);
 80			}
 81			return this._validationKey;
 82		}
 83	};
 84/**
 85 * @param {String} value the key used to generate HMAC
 86 * @throws {Yii.CException} if the key is empty
 87 */
 88Yii.CSecurityManager.prototype.setValidationKey = function (value) {
 89		if(!php.empty(value)) {
 90			this._validationKey=value;
 91		}
 92		else {
 93			throw new Yii.CException(Yii.t('yii','CSecurityManager.validationKey cannot be empty.'));
 94		}
 95	};
 96/**
 97 * @returns {String} the private key used to encrypt/decrypt data.
 98 * If the key is not explicitly set, a random one is generated and returned.
 99 */
100Yii.CSecurityManager.prototype.getEncryptionKey = function () {
101		var key;
102		if(this._encryptionKey!==null) {
103			return this._encryptionKey;
104		}
105		else {
106			if((key=Yii.app().getGlobalState(this.STATE_ENCRYPTION_KEY))!==null) {
107				this.setEncryptionKey(key);
108			}
109			else {
110				key=this.generateRandomKey();
111				this.setEncryptionKey(key);
112				Yii.app().setGlobalState(this.STATE_ENCRYPTION_KEY,key);
113			}
114			return this._encryptionKey;
115		}
116	};
117/**
118 * @param {String} value the key used to encrypt/decrypt data.
119 * @throws {Yii.CException} if the key is empty
120 */
121Yii.CSecurityManager.prototype.setEncryptionKey = function (value) {
122		if(!php.empty(value)) {
123			this._encryptionKey=value;
124		}
125		else {
126			throw new Yii.CException(Yii.t('yii','CSecurityManager.encryptionKey cannot be empty.'));
127		}
128	};
129/**
130 * This method has been deprecated since version 1.1.3.
131 * Please use {@link hashAlgorithm} instead.
132 */
133Yii.CSecurityManager.prototype.getValidation = function () {
134		return this.hashAlgorithm;
135	};
136/**
137 * This method has been deprecated since version 1.1.3.
138 * Please use {@link hashAlgorithm} instead.
139 * @param {String} value -
140 */
141Yii.CSecurityManager.prototype.setValidation = function (value) {
142		this.hashAlgorithm=value;
143	};
144/**
145 * Encrypts data.
146 * @param {String} data data to be encrypted.
147 * @param {String} key the decryption key. This defaults to null, meaning using {@link getEncryptionKey EncryptionKey}.
148 * @returns {String} the encrypted data
149 * @throws {Yii.CException} if PHP Mcrypt extension is not loaded
150 */
151Yii.CSecurityManager.prototype.encrypt = function (data, key) {
152		var module, iv, encrypted;
153		if (key === undefined) {
154			key = null;
155		}
156		module=this.openCryptModule();
157		key=key===null ? php.md5(this.getEncryptionKey()) : key;
158		encrypted = module.encrypt(key, data);
159		return encrypted;
160	};
161/**
162 * Decrypts data
163 * @param {String} data data to be decrypted.
164 * @param {String} key the decryption key. This defaults to null, meaning using {@link getEncryptionKey EncryptionKey}.
165 * @returns {String} the decrypted data
166 * @throws {Yii.CException} if PHP Mcrypt extension is not loaded
167 */
168Yii.CSecurityManager.prototype.decrypt = function (data, key) {
169		var module, ivSize, iv, decrypted;
170		if (key === undefined) {
171			key = null;
172		}
173		module=this.openCryptModule();
174		key=key===null ? php.md5(this.getEncryptionKey()) : key;
175		decrypted = module.decrypt(key, data);
176		return decrypted;
177	};
178/**
179 * Opens the mcrypt module with the configuration specified in {@link cryptAlgorithm}.
180 * @returns {Resource} the mycrypt module handle.
181 * @since 1.1.3
182 */
183Yii.CSecurityManager.prototype.openCryptModule = function () {
184		var module;
185		if(sjcl !== undefined) {
186			return sjcl;
187		}
188		else {
189			throw new Yii.CException(Yii.t('yii','CSecurityManager requires the Stanford Javascript Crypto Library to be loaded in order to use data encryption feature.'));
190		}
191	};
192/**
193 * Prefixes data with an HMAC.
194 * @param {String} data data to be hashed.
195 * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
196 * @returns {String} data prefixed with HMAC
197 */
198Yii.CSecurityManager.prototype.hashData = function (data, key) {
199		if (key === undefined) {
200			key = null;
201		}
202		return this.computeHMAC(data,key)+data;
203	};
204/**
205 * Validates if data is tampered.
206 * @param {String} data data to be validated. The data must be previously
207 * generated using {@link hashData()}.
208 * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
209 * @returns {String} the real data with HMAC stripped off. False if the data
210 * is tampered.
211 */
212Yii.CSecurityManager.prototype.validateData = function (data, key) {
213		var len, hmac, data2;
214		if (key === undefined) {
215			key = null;
216		}
217		len=php.strlen(this.computeHMAC('test'));
218		
219		if(php.strlen(data)>=len) {
220			hmac=data.slice(0, len);
221			data2=data.slice(len);
222			return hmac===this.computeHMAC(data2,key)?data2:false;
223		}
224		else {
225			return false;
226		}
227	};
228/**
229 * Computes the HMAC for the data with {@link getValidationKey ValidationKey}.
230 * @param {String} data data to be generated HMAC
231 * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
232 * @returns {String} the HMAC for the data
233 */
234Yii.CSecurityManager.prototype.computeHMAC = function (data, key) {
235		var pack, func, hmac;
236		if (key === undefined) {
237			key = null;
238		}
239		if(key===null) {
240			key=this.getValidationKey();
241		}
242		hmac = new sjcl.misc.hmac(key);
243		return php.md5(hmac.encrypt(data).join(""));		
244		
245};
246