PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms 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. */
  35. Yii.CSecurityManager = function CSecurityManager() {
  36. };
  37. Yii.CSecurityManager.prototype = new Yii.CApplicationComponent();
  38. Yii.CSecurityManager.prototype.constructor = Yii.CSecurityManager;
  39. /**
  40. * @const
  41. */
  42. Yii.CSecurityManager.STATE_VALIDATION_KEY = 'Yii.CSecurityManager.validationkey';
  43. /**
  44. * @const
  45. */
  46. Yii.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. */
  53. Yii.CSecurityManager.prototype.hashAlgorithm = 'sha1';
  54. Yii.CSecurityManager.prototype._validationKey = null;
  55. Yii.CSecurityManager.prototype._encryptionKey = null;
  56. /**
  57. * @returns {String} a randomly generated private key
  58. */
  59. Yii.CSecurityManager.prototype.generateRandomKey = function () {
  60. return php.sprintf('%08x%08x%08x%08x',php.mt_rand(),php.mt_rand(),php.mt_rand(),php.mt_rand());
  61. };
  62. /**
  63. * @returns {String} the private key used to generate HMAC.
  64. * If the key is not explicitly set, a random one is generated and returned.
  65. */
  66. Yii.CSecurityManager.prototype.getValidationKey = function () {
  67. var key;
  68. if(this._validationKey!==null) {
  69. return this._validationKey;
  70. }
  71. else {
  72. if((key=Yii.app().getGlobalState(this.STATE_VALIDATION_KEY))!==null) {
  73. this.setValidationKey(key);
  74. }
  75. else {
  76. key=this.generateRandomKey();
  77. this.setValidationKey(key);
  78. Yii.app().setGlobalState(this.STATE_VALIDATION_KEY,key);
  79. }
  80. return this._validationKey;
  81. }
  82. };
  83. /**
  84. * @param {String} value the key used to generate HMAC
  85. * @throws {Yii.CException} if the key is empty
  86. */
  87. Yii.CSecurityManager.prototype.setValidationKey = function (value) {
  88. if(!php.empty(value)) {
  89. this._validationKey=value;
  90. }
  91. else {
  92. throw new Yii.CException(Yii.t('yii','CSecurityManager.validationKey cannot be empty.'));
  93. }
  94. };
  95. /**
  96. * @returns {String} the private key used to encrypt/decrypt data.
  97. * If the key is not explicitly set, a random one is generated and returned.
  98. */
  99. Yii.CSecurityManager.prototype.getEncryptionKey = function () {
  100. var key;
  101. if(this._encryptionKey!==null) {
  102. return this._encryptionKey;
  103. }
  104. else {
  105. if((key=Yii.app().getGlobalState(this.STATE_ENCRYPTION_KEY))!==null) {
  106. this.setEncryptionKey(key);
  107. }
  108. else {
  109. key=this.generateRandomKey();
  110. this.setEncryptionKey(key);
  111. Yii.app().setGlobalState(this.STATE_ENCRYPTION_KEY,key);
  112. }
  113. return this._encryptionKey;
  114. }
  115. };
  116. /**
  117. * @param {String} value the key used to encrypt/decrypt data.
  118. * @throws {Yii.CException} if the key is empty
  119. */
  120. Yii.CSecurityManager.prototype.setEncryptionKey = function (value) {
  121. if(!php.empty(value)) {
  122. this._encryptionKey=value;
  123. }
  124. else {
  125. throw new Yii.CException(Yii.t('yii','CSecurityManager.encryptionKey cannot be empty.'));
  126. }
  127. };
  128. /**
  129. * This method has been deprecated since version 1.1.3.
  130. * Please use {@link hashAlgorithm} instead.
  131. */
  132. Yii.CSecurityManager.prototype.getValidation = function () {
  133. return this.hashAlgorithm;
  134. };
  135. /**
  136. * This method has been deprecated since version 1.1.3.
  137. * Please use {@link hashAlgorithm} instead.
  138. * @param {String} value -
  139. */
  140. Yii.CSecurityManager.prototype.setValidation = function (value) {
  141. this.hashAlgorithm=value;
  142. };
  143. /**
  144. * Encrypts data.
  145. * @param {String} data data to be encrypted.
  146. * @param {String} key the decryption key. This defaults to null, meaning using {@link getEncryptionKey EncryptionKey}.
  147. * @returns {String} the encrypted data
  148. * @throws {Yii.CException} if PHP Mcrypt extension is not loaded
  149. */
  150. Yii.CSecurityManager.prototype.encrypt = function (data, key) {
  151. var module, iv, encrypted;
  152. if (key === undefined) {
  153. key = null;
  154. }
  155. module=this.openCryptModule();
  156. key=key===null ? php.md5(this.getEncryptionKey()) : key;
  157. encrypted = module.encrypt(key, data);
  158. return encrypted;
  159. };
  160. /**
  161. * Decrypts data
  162. * @param {String} data data to be decrypted.
  163. * @param {String} key the decryption key. This defaults to null, meaning using {@link getEncryptionKey EncryptionKey}.
  164. * @returns {String} the decrypted data
  165. * @throws {Yii.CException} if PHP Mcrypt extension is not loaded
  166. */
  167. Yii.CSecurityManager.prototype.decrypt = function (data, key) {
  168. var module, ivSize, iv, decrypted;
  169. if (key === undefined) {
  170. key = null;
  171. }
  172. module=this.openCryptModule();
  173. key=key===null ? php.md5(this.getEncryptionKey()) : key;
  174. decrypted = module.decrypt(key, data);
  175. return decrypted;
  176. };
  177. /**
  178. * Opens the mcrypt module with the configuration specified in {@link cryptAlgorithm}.
  179. * @returns {Resource} the mycrypt module handle.
  180. * @since 1.1.3
  181. */
  182. Yii.CSecurityManager.prototype.openCryptModule = function () {
  183. var module;
  184. if(sjcl !== undefined) {
  185. return sjcl;
  186. }
  187. else {
  188. throw new Yii.CException(Yii.t('yii','CSecurityManager requires the Stanford Javascript Crypto Library to be loaded in order to use data encryption feature.'));
  189. }
  190. };
  191. /**
  192. * Prefixes data with an HMAC.
  193. * @param {String} data data to be hashed.
  194. * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
  195. * @returns {String} data prefixed with HMAC
  196. */
  197. Yii.CSecurityManager.prototype.hashData = function (data, key) {
  198. if (key === undefined) {
  199. key = null;
  200. }
  201. return this.computeHMAC(data,key)+data;
  202. };
  203. /**
  204. * Validates if data is tampered.
  205. * @param {String} data data to be validated. The data must be previously
  206. * generated using {@link hashData()}.
  207. * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
  208. * @returns {String} the real data with HMAC stripped off. False if the data
  209. * is tampered.
  210. */
  211. Yii.CSecurityManager.prototype.validateData = function (data, key) {
  212. var len, hmac, data2;
  213. if (key === undefined) {
  214. key = null;
  215. }
  216. len=php.strlen(this.computeHMAC('test'));
  217. if(php.strlen(data)>=len) {
  218. hmac=data.slice(0, len);
  219. data2=data.slice(len);
  220. return hmac===this.computeHMAC(data2,key)?data2:false;
  221. }
  222. else {
  223. return false;
  224. }
  225. };
  226. /**
  227. * Computes the HMAC for the data with {@link getValidationKey ValidationKey}.
  228. * @param {String} data data to be generated HMAC
  229. * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
  230. * @returns {String} the HMAC for the data
  231. */
  232. Yii.CSecurityManager.prototype.computeHMAC = function (data, key) {
  233. var pack, func, hmac;
  234. if (key === undefined) {
  235. key = null;
  236. }
  237. if(key===null) {
  238. key=this.getValidationKey();
  239. }
  240. hmac = new sjcl.misc.hmac(key);
  241. return php.md5(hmac.encrypt(data).join(""));
  242. };