├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── menu
│ │ │ │ └── menu_main.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── values
│ │ │ │ ├── styles.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ └── strings.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ └── layout
│ │ │ │ ├── activity_real_library.xml
│ │ │ │ ├── activity_stress_test.xml
│ │ │ │ ├── activity_line_endings.xml
│ │ │ │ ├── activity_evaluate_js_string.xml
│ │ │ │ ├── activity_destroy.xml
│ │ │ │ ├── activity_percentage.xml
│ │ │ │ ├── activity_call_js_function.xml
│ │ │ │ ├── activity_character_escape.xml
│ │ │ │ └── activity_main.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── evgenii
│ │ │ │ └── jsevaluatortests
│ │ │ │ ├── JSUtils.java
│ │ │ │ ├── LineEndingsActivity.java
│ │ │ │ ├── DestroyActivity.java
│ │ │ │ ├── PercentageActivity.java
│ │ │ │ ├── EvaluateJsStringActivity.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── CallJsFunctionActivity.java
│ │ │ │ ├── CharacterEscape.java
│ │ │ │ ├── StressTestActivity.java
│ │ │ │ └── RealLibrary.java
│ │ ├── AndroidManifest.xml
│ │ └── assets
│ │ │ └── real_library
│ │ │ └── cryptojs.js
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── evgenii
│ │ └── jsevaluatortests
│ │ ├── mocks
│ │ ├── HandlerWrapperMock.java
│ │ ├── CallJavaResultInterfaceMock.java
│ │ ├── JsCallbackMock.java
│ │ └── WebViewWrapperMock.java
│ │ ├── JavaScriptInterfaceTest.java
│ │ ├── RealLibraryTests.java
│ │ ├── StressTestActivityTests.java
│ │ ├── LineEndingsActivityTests.java
│ │ ├── JsFunctionCallFormatterTests.java
│ │ ├── CharacterEscapeTests.java
│ │ ├── DestroyActivityTests.java
│ │ ├── EvaluateJsActivityTests.java
│ │ ├── PercentageActivityTest.java
│ │ ├── WebViewWrapperTest.java
│ │ ├── CallJsFunctionActivityTests.java
│ │ └── JsEvaluatorTests.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── jsevaluator
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ └── values
│ │ │ └── strings.xml
│ │ └── java
│ │ └── com
│ │ └── evgenii
│ │ └── jsevaluator
│ │ ├── interfaces
│ │ ├── HandlerWrapperInterface.java
│ │ ├── CallJavaResultInterface.java
│ │ ├── JsCallback.java
│ │ ├── WebViewWrapperInterface.java
│ │ └── JsEvaluatorInterface.java
│ │ ├── HandlerWrapper.java
│ │ ├── JavaScriptInterface.java
│ │ ├── JsFunctionCallFormatter.java
│ │ ├── WebViewWrapper.java
│ │ └── JsEvaluator.java
├── consumer-proguard-rules.pro
├── .gitignore
├── proguard-rules.pro
└── build.gradle
├── .gitignore
├── js_evaluator_screenshot_2.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── js_evaluator_screenshot_1_2014_08_30.png
├── CHANGELOG.md
├── LICENSE
├── gradle.properties
├── gradlew.bat
├── gradlew
└── README.md
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':jsevaluator'
2 |
--------------------------------------------------------------------------------
/jsevaluator/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
242 |
243 |
244 |
245 |
246 | Or run as `Android JUnit Test` for unit testing.
247 |
248 | Android versions tested:
249 |
250 | * 4.0.3 (Ice Cream Sandwich)
251 | * 4.1.2, 4.2.2, 4.3 (Jelly Bean)
252 | * 4.4.2 (KitKat)
253 | * 5.0, 5.1 (Lollipop)
254 | * 6.0 (Marshmallow)
255 | * 8.0 (Oreo)
256 |
257 | ## Thanks 👍
258 |
259 | * [codebymikey](https://github.com/codebymikey) for adding error handling.
260 | * [xbao](https://github.com/xbao) for adding a Gradle file.
261 | * [clydzik](https://github.com/clydzik) for fixing a [memory leak](https://github.com/evgenyneu/js-evaluator-for-android/pull/40) and simplifying the code.
262 |
263 |
264 | ## Feedback is welcome
265 |
266 | If you have any issues or need help please do not hesitate to create an issue ticket.
267 |
268 |
--------------------------------------------------------------------------------
/app/src/main/assets/real_library/cryptojs.js:
--------------------------------------------------------------------------------
1 | /*
2 | CryptoJS v3.1.2
3 | code.google.com/p/crypto-js
4 | (c) 2009-2013 by Jeff Mott. All rights reserved.
5 | code.google.com/p/crypto-js/wiki/License
6 | */
7 | /**
8 | * CryptoJS core components.
9 | */
10 | var CryptoJS = CryptoJS || (function (Math, undefined) {
11 | /**
12 | * CryptoJS namespace.
13 | */
14 | var C = {};
15 |
16 | /**
17 | * Library namespace.
18 | */
19 | var C_lib = C.lib = {};
20 |
21 | /**
22 | * Base object for prototypal inheritance.
23 | */
24 | var Base = C_lib.Base = (function () {
25 | function F() {}
26 |
27 | return {
28 | /**
29 | * Creates a new object that inherits from this object.
30 | *
31 | * @param {Object} overrides Properties to copy into the new object.
32 | *
33 | * @return {Object} The new object.
34 | *
35 | * @static
36 | *
37 | * @example
38 | *
39 | * var MyType = CryptoJS.lib.Base.extend({
40 | * field: 'value',
41 | *
42 | * method: function () {
43 | * }
44 | * });
45 | */
46 | extend: function (overrides) {
47 | // Spawn
48 | F.prototype = this;
49 | var subtype = new F();
50 |
51 | // Augment
52 | if (overrides) {
53 | subtype.mixIn(overrides);
54 | }
55 |
56 | // Create default initializer
57 | if (!subtype.hasOwnProperty('init')) {
58 | subtype.init = function () {
59 | subtype.$super.init.apply(this, arguments);
60 | };
61 | }
62 |
63 | // Initializer's prototype is the subtype object
64 | subtype.init.prototype = subtype;
65 |
66 | // Reference supertype
67 | subtype.$super = this;
68 |
69 | return subtype;
70 | },
71 |
72 | /**
73 | * Extends this object and runs the init method.
74 | * Arguments to create() will be passed to init().
75 | *
76 | * @return {Object} The new object.
77 | *
78 | * @static
79 | *
80 | * @example
81 | *
82 | * var instance = MyType.create();
83 | */
84 | create: function () {
85 | var instance = this.extend();
86 | instance.init.apply(instance, arguments);
87 |
88 | return instance;
89 | },
90 |
91 | /**
92 | * Initializes a newly created object.
93 | * Override this method to add some logic when your objects are created.
94 | *
95 | * @example
96 | *
97 | * var MyType = CryptoJS.lib.Base.extend({
98 | * init: function () {
99 | * // ...
100 | * }
101 | * });
102 | */
103 | init: function () {
104 | },
105 |
106 | /**
107 | * Copies properties into this object.
108 | *
109 | * @param {Object} properties The properties to mix in.
110 | *
111 | * @example
112 | *
113 | * MyType.mixIn({
114 | * field: 'value'
115 | * });
116 | */
117 | mixIn: function (properties) {
118 | for (var propertyName in properties) {
119 | if (properties.hasOwnProperty(propertyName)) {
120 | this[propertyName] = properties[propertyName];
121 | }
122 | }
123 |
124 | // IE won't copy toString using the loop above
125 | if (properties.hasOwnProperty('toString')) {
126 | this.toString = properties.toString;
127 | }
128 | },
129 |
130 | /**
131 | * Creates a copy of this object.
132 | *
133 | * @return {Object} The clone.
134 | *
135 | * @example
136 | *
137 | * var clone = instance.clone();
138 | */
139 | clone: function () {
140 | return this.init.prototype.extend(this);
141 | }
142 | };
143 | }());
144 |
145 | /**
146 | * An array of 32-bit words.
147 | *
148 | * @property {Array} words The array of 32-bit words.
149 | * @property {number} sigBytes The number of significant bytes in this word array.
150 | */
151 | var WordArray = C_lib.WordArray = Base.extend({
152 | /**
153 | * Initializes a newly created word array.
154 | *
155 | * @param {Array} words (Optional) An array of 32-bit words.
156 | * @param {number} sigBytes (Optional) The number of significant bytes in the words.
157 | *
158 | * @example
159 | *
160 | * var wordArray = CryptoJS.lib.WordArray.create();
161 | * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
162 | * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
163 | */
164 | init: function (words, sigBytes) {
165 | words = this.words = words || [];
166 |
167 | if (sigBytes != undefined) {
168 | this.sigBytes = sigBytes;
169 | } else {
170 | this.sigBytes = words.length * 4;
171 | }
172 | },
173 |
174 | /**
175 | * Converts this word array to a string.
176 | *
177 | * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
178 | *
179 | * @return {string} The stringified word array.
180 | *
181 | * @example
182 | *
183 | * var string = wordArray + '';
184 | * var string = wordArray.toString();
185 | * var string = wordArray.toString(CryptoJS.enc.Utf8);
186 | */
187 | toString: function (encoder) {
188 | return (encoder || Hex).stringify(this);
189 | },
190 |
191 | /**
192 | * Concatenates a word array to this word array.
193 | *
194 | * @param {WordArray} wordArray The word array to append.
195 | *
196 | * @return {WordArray} This word array.
197 | *
198 | * @example
199 | *
200 | * wordArray1.concat(wordArray2);
201 | */
202 | concat: function (wordArray) {
203 | // Shortcuts
204 | var thisWords = this.words;
205 | var thatWords = wordArray.words;
206 | var thisSigBytes = this.sigBytes;
207 | var thatSigBytes = wordArray.sigBytes;
208 |
209 | // Clamp excess bits
210 | this.clamp();
211 |
212 | // Concat
213 | if (thisSigBytes % 4) {
214 | // Copy one byte at a time
215 | for (var i = 0; i < thatSigBytes; i++) {
216 | var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
217 | thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
218 | }
219 | } else if (thatWords.length > 0xffff) {
220 | // Copy one word at a time
221 | for (var i = 0; i < thatSigBytes; i += 4) {
222 | thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
223 | }
224 | } else {
225 | // Copy all words at once
226 | thisWords.push.apply(thisWords, thatWords);
227 | }
228 | this.sigBytes += thatSigBytes;
229 |
230 | // Chainable
231 | return this;
232 | },
233 |
234 | /**
235 | * Removes insignificant bits.
236 | *
237 | * @example
238 | *
239 | * wordArray.clamp();
240 | */
241 | clamp: function () {
242 | // Shortcuts
243 | var words = this.words;
244 | var sigBytes = this.sigBytes;
245 |
246 | // Clamp
247 | words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
248 | words.length = Math.ceil(sigBytes / 4);
249 | },
250 |
251 | /**
252 | * Creates a copy of this word array.
253 | *
254 | * @return {WordArray} The clone.
255 | *
256 | * @example
257 | *
258 | * var clone = wordArray.clone();
259 | */
260 | clone: function () {
261 | var clone = Base.clone.call(this);
262 | clone.words = this.words.slice(0);
263 |
264 | return clone;
265 | },
266 |
267 | /**
268 | * Creates a word array filled with random bytes.
269 | *
270 | * @param {number} nBytes The number of random bytes to generate.
271 | *
272 | * @return {WordArray} The random word array.
273 | *
274 | * @static
275 | *
276 | * @example
277 | *
278 | * var wordArray = CryptoJS.lib.WordArray.random(16);
279 | */
280 | random: function (nBytes) {
281 | var words = [];
282 | for (var i = 0; i < nBytes; i += 4) {
283 | words.push((Math.random() * 0x100000000) | 0);
284 | }
285 |
286 | return new WordArray.init(words, nBytes);
287 | }
288 | });
289 |
290 | /**
291 | * Encoder namespace.
292 | */
293 | var C_enc = C.enc = {};
294 |
295 | /**
296 | * Hex encoding strategy.
297 | */
298 | var Hex = C_enc.Hex = {
299 | /**
300 | * Converts a word array to a hex string.
301 | *
302 | * @param {WordArray} wordArray The word array.
303 | *
304 | * @return {string} The hex string.
305 | *
306 | * @static
307 | *
308 | * @example
309 | *
310 | * var hexString = CryptoJS.enc.Hex.stringify(wordArray);
311 | */
312 | stringify: function (wordArray) {
313 | // Shortcuts
314 | var words = wordArray.words;
315 | var sigBytes = wordArray.sigBytes;
316 |
317 | // Convert
318 | var hexChars = [];
319 | for (var i = 0; i < sigBytes; i++) {
320 | var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
321 | hexChars.push((bite >>> 4).toString(16));
322 | hexChars.push((bite & 0x0f).toString(16));
323 | }
324 |
325 | return hexChars.join('');
326 | },
327 |
328 | /**
329 | * Converts a hex string to a word array.
330 | *
331 | * @param {string} hexStr The hex string.
332 | *
333 | * @return {WordArray} The word array.
334 | *
335 | * @static
336 | *
337 | * @example
338 | *
339 | * var wordArray = CryptoJS.enc.Hex.parse(hexString);
340 | */
341 | parse: function (hexStr) {
342 | // Shortcut
343 | var hexStrLength = hexStr.length;
344 |
345 | // Convert
346 | var words = [];
347 | for (var i = 0; i < hexStrLength; i += 2) {
348 | words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
349 | }
350 |
351 | return new WordArray.init(words, hexStrLength / 2);
352 | }
353 | };
354 |
355 | /**
356 | * Latin1 encoding strategy.
357 | */
358 | var Latin1 = C_enc.Latin1 = {
359 | /**
360 | * Converts a word array to a Latin1 string.
361 | *
362 | * @param {WordArray} wordArray The word array.
363 | *
364 | * @return {string} The Latin1 string.
365 | *
366 | * @static
367 | *
368 | * @example
369 | *
370 | * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
371 | */
372 | stringify: function (wordArray) {
373 | // Shortcuts
374 | var words = wordArray.words;
375 | var sigBytes = wordArray.sigBytes;
376 |
377 | // Convert
378 | var latin1Chars = [];
379 | for (var i = 0; i < sigBytes; i++) {
380 | var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
381 | latin1Chars.push(String.fromCharCode(bite));
382 | }
383 |
384 | return latin1Chars.join('');
385 | },
386 |
387 | /**
388 | * Converts a Latin1 string to a word array.
389 | *
390 | * @param {string} latin1Str The Latin1 string.
391 | *
392 | * @return {WordArray} The word array.
393 | *
394 | * @static
395 | *
396 | * @example
397 | *
398 | * var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
399 | */
400 | parse: function (latin1Str) {
401 | // Shortcut
402 | var latin1StrLength = latin1Str.length;
403 |
404 | // Convert
405 | var words = [];
406 | for (var i = 0; i < latin1StrLength; i++) {
407 | words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
408 | }
409 |
410 | return new WordArray.init(words, latin1StrLength);
411 | }
412 | };
413 |
414 | /**
415 | * UTF-8 encoding strategy.
416 | */
417 | var Utf8 = C_enc.Utf8 = {
418 | /**
419 | * Converts a word array to a UTF-8 string.
420 | *
421 | * @param {WordArray} wordArray The word array.
422 | *
423 | * @return {string} The UTF-8 string.
424 | *
425 | * @static
426 | *
427 | * @example
428 | *
429 | * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
430 | */
431 | stringify: function (wordArray) {
432 | try {
433 | return decodeURIComponent(escape(Latin1.stringify(wordArray)));
434 | } catch (e) {
435 | throw new Error('Malformed UTF-8 data');
436 | }
437 | },
438 |
439 | /**
440 | * Converts a UTF-8 string to a word array.
441 | *
442 | * @param {string} utf8Str The UTF-8 string.
443 | *
444 | * @return {WordArray} The word array.
445 | *
446 | * @static
447 | *
448 | * @example
449 | *
450 | * var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
451 | */
452 | parse: function (utf8Str) {
453 | return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
454 | }
455 | };
456 |
457 | /**
458 | * Abstract buffered block algorithm template.
459 | *
460 | * The property blockSize must be implemented in a concrete subtype.
461 | *
462 | * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
463 | */
464 | var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
465 | /**
466 | * Resets this block algorithm's data buffer to its initial state.
467 | *
468 | * @example
469 | *
470 | * bufferedBlockAlgorithm.reset();
471 | */
472 | reset: function () {
473 | // Initial values
474 | this._data = new WordArray.init();
475 | this._nDataBytes = 0;
476 | },
477 |
478 | /**
479 | * Adds new data to this block algorithm's buffer.
480 | *
481 | * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
482 | *
483 | * @example
484 | *
485 | * bufferedBlockAlgorithm._append('data');
486 | * bufferedBlockAlgorithm._append(wordArray);
487 | */
488 | _append: function (data) {
489 | // Convert string to WordArray, else assume WordArray already
490 | if (typeof data == 'string') {
491 | data = Utf8.parse(data);
492 | }
493 |
494 | // Append
495 | this._data.concat(data);
496 | this._nDataBytes += data.sigBytes;
497 | },
498 |
499 | /**
500 | * Processes available data blocks.
501 | *
502 | * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
503 | *
504 | * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
505 | *
506 | * @return {WordArray} The processed data.
507 | *
508 | * @example
509 | *
510 | * var processedData = bufferedBlockAlgorithm._process();
511 | * var processedData = bufferedBlockAlgorithm._process(!!'flush');
512 | */
513 | _process: function (doFlush) {
514 | // Shortcuts
515 | var data = this._data;
516 | var dataWords = data.words;
517 | var dataSigBytes = data.sigBytes;
518 | var blockSize = this.blockSize;
519 | var blockSizeBytes = blockSize * 4;
520 |
521 | // Count blocks ready
522 | var nBlocksReady = dataSigBytes / blockSizeBytes;
523 | if (doFlush) {
524 | // Round up to include partial blocks
525 | nBlocksReady = Math.ceil(nBlocksReady);
526 | } else {
527 | // Round down to include only full blocks,
528 | // less the number of blocks that must remain in the buffer
529 | nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
530 | }
531 |
532 | // Count words ready
533 | var nWordsReady = nBlocksReady * blockSize;
534 |
535 | // Count bytes ready
536 | var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
537 |
538 | // Process blocks
539 | if (nWordsReady) {
540 | for (var offset = 0; offset < nWordsReady; offset += blockSize) {
541 | // Perform concrete-algorithm logic
542 | this._doProcessBlock(dataWords, offset);
543 | }
544 |
545 | // Remove processed words
546 | var processedWords = dataWords.splice(0, nWordsReady);
547 | data.sigBytes -= nBytesReady;
548 | }
549 |
550 | // Return processed words
551 | return new WordArray.init(processedWords, nBytesReady);
552 | },
553 |
554 | /**
555 | * Creates a copy of this object.
556 | *
557 | * @return {Object} The clone.
558 | *
559 | * @example
560 | *
561 | * var clone = bufferedBlockAlgorithm.clone();
562 | */
563 | clone: function () {
564 | var clone = Base.clone.call(this);
565 | clone._data = this._data.clone();
566 |
567 | return clone;
568 | },
569 |
570 | _minBufferSize: 0
571 | });
572 |
573 | /**
574 | * Abstract hasher template.
575 | *
576 | * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
577 | */
578 | var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
579 | /**
580 | * Configuration options.
581 | */
582 | cfg: Base.extend(),
583 |
584 | /**
585 | * Initializes a newly created hasher.
586 | *
587 | * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
588 | *
589 | * @example
590 | *
591 | * var hasher = CryptoJS.algo.SHA256.create();
592 | */
593 | init: function (cfg) {
594 | // Apply config defaults
595 | this.cfg = this.cfg.extend(cfg);
596 |
597 | // Set initial values
598 | this.reset();
599 | },
600 |
601 | /**
602 | * Resets this hasher to its initial state.
603 | *
604 | * @example
605 | *
606 | * hasher.reset();
607 | */
608 | reset: function () {
609 | // Reset data buffer
610 | BufferedBlockAlgorithm.reset.call(this);
611 |
612 | // Perform concrete-hasher logic
613 | this._doReset();
614 | },
615 |
616 | /**
617 | * Updates this hasher with a message.
618 | *
619 | * @param {WordArray|string} messageUpdate The message to append.
620 | *
621 | * @return {Hasher} This hasher.
622 | *
623 | * @example
624 | *
625 | * hasher.update('message');
626 | * hasher.update(wordArray);
627 | */
628 | update: function (messageUpdate) {
629 | // Append
630 | this._append(messageUpdate);
631 |
632 | // Update the hash
633 | this._process();
634 |
635 | // Chainable
636 | return this;
637 | },
638 |
639 | /**
640 | * Finalizes the hash computation.
641 | * Note that the finalize operation is effectively a destructive, read-once operation.
642 | *
643 | * @param {WordArray|string} messageUpdate (Optional) A final message update.
644 | *
645 | * @return {WordArray} The hash.
646 | *
647 | * @example
648 | *
649 | * var hash = hasher.finalize();
650 | * var hash = hasher.finalize('message');
651 | * var hash = hasher.finalize(wordArray);
652 | */
653 | finalize: function (messageUpdate) {
654 | // Final message update
655 | if (messageUpdate) {
656 | this._append(messageUpdate);
657 | }
658 |
659 | // Perform concrete-hasher logic
660 | var hash = this._doFinalize();
661 |
662 | return hash;
663 | },
664 |
665 | blockSize: 512/32,
666 |
667 | /**
668 | * Creates a shortcut function to a hasher's object interface.
669 | *
670 | * @param {Hasher} hasher The hasher to create a helper for.
671 | *
672 | * @return {Function} The shortcut function.
673 | *
674 | * @static
675 | *
676 | * @example
677 | *
678 | * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
679 | */
680 | _createHelper: function (hasher) {
681 | return function (message, cfg) {
682 | return new hasher.init(cfg).finalize(message);
683 | };
684 | },
685 |
686 | /**
687 | * Creates a shortcut function to the HMAC's object interface.
688 | *
689 | * @param {Hasher} hasher The hasher to use in this HMAC helper.
690 | *
691 | * @return {Function} The shortcut function.
692 | *
693 | * @static
694 | *
695 | * @example
696 | *
697 | * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
698 | */
699 | _createHmacHelper: function (hasher) {
700 | return function (message, key) {
701 | return new C_algo.HMAC.init(hasher, key).finalize(message);
702 | };
703 | }
704 | });
705 |
706 | /**
707 | * Algorithm namespace.
708 | */
709 | var C_algo = C.algo = {};
710 |
711 | return C;
712 | }(Math));
713 |
714 | /*
715 | CryptoJS v3.1.2
716 | code.google.com/p/crypto-js
717 | (c) 2009-2013 by Jeff Mott. All rights reserved.
718 | code.google.com/p/crypto-js/wiki/License
719 | */
720 | (function () {
721 | // Shortcuts
722 | var C = CryptoJS;
723 | var C_lib = C.lib;
724 | var WordArray = C_lib.WordArray;
725 | var C_enc = C.enc;
726 |
727 | /**
728 | * Base64 encoding strategy.
729 | */
730 | var Base64 = C_enc.Base64 = {
731 | /**
732 | * Converts a word array to a Base64 string.
733 | *
734 | * @param {WordArray} wordArray The word array.
735 | *
736 | * @return {string} The Base64 string.
737 | *
738 | * @static
739 | *
740 | * @example
741 | *
742 | * var base64String = CryptoJS.enc.Base64.stringify(wordArray);
743 | */
744 | stringify: function (wordArray) {
745 | // Shortcuts
746 | var words = wordArray.words;
747 | var sigBytes = wordArray.sigBytes;
748 | var map = this._map;
749 |
750 | // Clamp excess bits
751 | wordArray.clamp();
752 |
753 | // Convert
754 | var base64Chars = [];
755 | for (var i = 0; i < sigBytes; i += 3) {
756 | var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
757 | var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
758 | var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
759 |
760 | var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
761 |
762 | for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
763 | base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
764 | }
765 | }
766 |
767 | // Add padding
768 | var paddingChar = map.charAt(64);
769 | if (paddingChar) {
770 | while (base64Chars.length % 4) {
771 | base64Chars.push(paddingChar);
772 | }
773 | }
774 |
775 | return base64Chars.join('');
776 | },
777 |
778 | /**
779 | * Converts a Base64 string to a word array.
780 | *
781 | * @param {string} base64Str The Base64 string.
782 | *
783 | * @return {WordArray} The word array.
784 | *
785 | * @static
786 | *
787 | * @example
788 | *
789 | * var wordArray = CryptoJS.enc.Base64.parse(base64String);
790 | */
791 | parse: function (base64Str) {
792 | // Shortcuts
793 | var base64StrLength = base64Str.length;
794 | var map = this._map;
795 |
796 | // Ignore padding
797 | var paddingChar = map.charAt(64);
798 | if (paddingChar) {
799 | var paddingIndex = base64Str.indexOf(paddingChar);
800 | if (paddingIndex != -1) {
801 | base64StrLength = paddingIndex;
802 | }
803 | }
804 |
805 | // Convert
806 | var words = [];
807 | var nBytes = 0;
808 | for (var i = 0; i < base64StrLength; i++) {
809 | if (i % 4) {
810 | var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2);
811 | var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2);
812 | words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8);
813 | nBytes++;
814 | }
815 | }
816 |
817 | return WordArray.create(words, nBytes);
818 | },
819 |
820 | _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
821 | };
822 | }());
823 |
824 | /*
825 | CryptoJS v3.1.2
826 | code.google.com/p/crypto-js
827 | (c) 2009-2013 by Jeff Mott. All rights reserved.
828 | code.google.com/p/crypto-js/wiki/License
829 | */
830 | (function (Math) {
831 | // Shortcuts
832 | var C = CryptoJS;
833 | var C_lib = C.lib;
834 | var WordArray = C_lib.WordArray;
835 | var Hasher = C_lib.Hasher;
836 | var C_algo = C.algo;
837 |
838 | // Constants table
839 | var T = [];
840 |
841 | // Compute constants
842 | (function () {
843 | for (var i = 0; i < 64; i++) {
844 | T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
845 | }
846 | }());
847 |
848 | /**
849 | * MD5 hash algorithm.
850 | */
851 | var MD5 = C_algo.MD5 = Hasher.extend({
852 | _doReset: function () {
853 | this._hash = new WordArray.init([
854 | 0x67452301, 0xefcdab89,
855 | 0x98badcfe, 0x10325476
856 | ]);
857 | },
858 |
859 | _doProcessBlock: function (M, offset) {
860 | // Swap endian
861 | for (var i = 0; i < 16; i++) {
862 | // Shortcuts
863 | var offset_i = offset + i;
864 | var M_offset_i = M[offset_i];
865 |
866 | M[offset_i] = (
867 | (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
868 | (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
869 | );
870 | }
871 |
872 | // Shortcuts
873 | var H = this._hash.words;
874 |
875 | var M_offset_0 = M[offset + 0];
876 | var M_offset_1 = M[offset + 1];
877 | var M_offset_2 = M[offset + 2];
878 | var M_offset_3 = M[offset + 3];
879 | var M_offset_4 = M[offset + 4];
880 | var M_offset_5 = M[offset + 5];
881 | var M_offset_6 = M[offset + 6];
882 | var M_offset_7 = M[offset + 7];
883 | var M_offset_8 = M[offset + 8];
884 | var M_offset_9 = M[offset + 9];
885 | var M_offset_10 = M[offset + 10];
886 | var M_offset_11 = M[offset + 11];
887 | var M_offset_12 = M[offset + 12];
888 | var M_offset_13 = M[offset + 13];
889 | var M_offset_14 = M[offset + 14];
890 | var M_offset_15 = M[offset + 15];
891 |
892 | // Working varialbes
893 | var a = H[0];
894 | var b = H[1];
895 | var c = H[2];
896 | var d = H[3];
897 |
898 | // Computation
899 | a = FF(a, b, c, d, M_offset_0, 7, T[0]);
900 | d = FF(d, a, b, c, M_offset_1, 12, T[1]);
901 | c = FF(c, d, a, b, M_offset_2, 17, T[2]);
902 | b = FF(b, c, d, a, M_offset_3, 22, T[3]);
903 | a = FF(a, b, c, d, M_offset_4, 7, T[4]);
904 | d = FF(d, a, b, c, M_offset_5, 12, T[5]);
905 | c = FF(c, d, a, b, M_offset_6, 17, T[6]);
906 | b = FF(b, c, d, a, M_offset_7, 22, T[7]);
907 | a = FF(a, b, c, d, M_offset_8, 7, T[8]);
908 | d = FF(d, a, b, c, M_offset_9, 12, T[9]);
909 | c = FF(c, d, a, b, M_offset_10, 17, T[10]);
910 | b = FF(b, c, d, a, M_offset_11, 22, T[11]);
911 | a = FF(a, b, c, d, M_offset_12, 7, T[12]);
912 | d = FF(d, a, b, c, M_offset_13, 12, T[13]);
913 | c = FF(c, d, a, b, M_offset_14, 17, T[14]);
914 | b = FF(b, c, d, a, M_offset_15, 22, T[15]);
915 |
916 | a = GG(a, b, c, d, M_offset_1, 5, T[16]);
917 | d = GG(d, a, b, c, M_offset_6, 9, T[17]);
918 | c = GG(c, d, a, b, M_offset_11, 14, T[18]);
919 | b = GG(b, c, d, a, M_offset_0, 20, T[19]);
920 | a = GG(a, b, c, d, M_offset_5, 5, T[20]);
921 | d = GG(d, a, b, c, M_offset_10, 9, T[21]);
922 | c = GG(c, d, a, b, M_offset_15, 14, T[22]);
923 | b = GG(b, c, d, a, M_offset_4, 20, T[23]);
924 | a = GG(a, b, c, d, M_offset_9, 5, T[24]);
925 | d = GG(d, a, b, c, M_offset_14, 9, T[25]);
926 | c = GG(c, d, a, b, M_offset_3, 14, T[26]);
927 | b = GG(b, c, d, a, M_offset_8, 20, T[27]);
928 | a = GG(a, b, c, d, M_offset_13, 5, T[28]);
929 | d = GG(d, a, b, c, M_offset_2, 9, T[29]);
930 | c = GG(c, d, a, b, M_offset_7, 14, T[30]);
931 | b = GG(b, c, d, a, M_offset_12, 20, T[31]);
932 |
933 | a = HH(a, b, c, d, M_offset_5, 4, T[32]);
934 | d = HH(d, a, b, c, M_offset_8, 11, T[33]);
935 | c = HH(c, d, a, b, M_offset_11, 16, T[34]);
936 | b = HH(b, c, d, a, M_offset_14, 23, T[35]);
937 | a = HH(a, b, c, d, M_offset_1, 4, T[36]);
938 | d = HH(d, a, b, c, M_offset_4, 11, T[37]);
939 | c = HH(c, d, a, b, M_offset_7, 16, T[38]);
940 | b = HH(b, c, d, a, M_offset_10, 23, T[39]);
941 | a = HH(a, b, c, d, M_offset_13, 4, T[40]);
942 | d = HH(d, a, b, c, M_offset_0, 11, T[41]);
943 | c = HH(c, d, a, b, M_offset_3, 16, T[42]);
944 | b = HH(b, c, d, a, M_offset_6, 23, T[43]);
945 | a = HH(a, b, c, d, M_offset_9, 4, T[44]);
946 | d = HH(d, a, b, c, M_offset_12, 11, T[45]);
947 | c = HH(c, d, a, b, M_offset_15, 16, T[46]);
948 | b = HH(b, c, d, a, M_offset_2, 23, T[47]);
949 |
950 | a = II(a, b, c, d, M_offset_0, 6, T[48]);
951 | d = II(d, a, b, c, M_offset_7, 10, T[49]);
952 | c = II(c, d, a, b, M_offset_14, 15, T[50]);
953 | b = II(b, c, d, a, M_offset_5, 21, T[51]);
954 | a = II(a, b, c, d, M_offset_12, 6, T[52]);
955 | d = II(d, a, b, c, M_offset_3, 10, T[53]);
956 | c = II(c, d, a, b, M_offset_10, 15, T[54]);
957 | b = II(b, c, d, a, M_offset_1, 21, T[55]);
958 | a = II(a, b, c, d, M_offset_8, 6, T[56]);
959 | d = II(d, a, b, c, M_offset_15, 10, T[57]);
960 | c = II(c, d, a, b, M_offset_6, 15, T[58]);
961 | b = II(b, c, d, a, M_offset_13, 21, T[59]);
962 | a = II(a, b, c, d, M_offset_4, 6, T[60]);
963 | d = II(d, a, b, c, M_offset_11, 10, T[61]);
964 | c = II(c, d, a, b, M_offset_2, 15, T[62]);
965 | b = II(b, c, d, a, M_offset_9, 21, T[63]);
966 |
967 | // Intermediate hash value
968 | H[0] = (H[0] + a) | 0;
969 | H[1] = (H[1] + b) | 0;
970 | H[2] = (H[2] + c) | 0;
971 | H[3] = (H[3] + d) | 0;
972 | },
973 |
974 | _doFinalize: function () {
975 | // Shortcuts
976 | var data = this._data;
977 | var dataWords = data.words;
978 |
979 | var nBitsTotal = this._nDataBytes * 8;
980 | var nBitsLeft = data.sigBytes * 8;
981 |
982 | // Add padding
983 | dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
984 |
985 | var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
986 | var nBitsTotalL = nBitsTotal;
987 | dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
988 | (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
989 | (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00)
990 | );
991 | dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
992 | (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
993 | (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00)
994 | );
995 |
996 | data.sigBytes = (dataWords.length + 1) * 4;
997 |
998 | // Hash final blocks
999 | this._process();
1000 |
1001 | // Shortcuts
1002 | var hash = this._hash;
1003 | var H = hash.words;
1004 |
1005 | // Swap endian
1006 | for (var i = 0; i < 4; i++) {
1007 | // Shortcut
1008 | var H_i = H[i];
1009 |
1010 | H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
1011 | (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
1012 | }
1013 |
1014 | // Return final computed hash
1015 | return hash;
1016 | },
1017 |
1018 | clone: function () {
1019 | var clone = Hasher.clone.call(this);
1020 | clone._hash = this._hash.clone();
1021 |
1022 | return clone;
1023 | }
1024 | });
1025 |
1026 | function FF(a, b, c, d, x, s, t) {
1027 | var n = a + ((b & c) | (~b & d)) + x + t;
1028 | return ((n << s) | (n >>> (32 - s))) + b;
1029 | }
1030 |
1031 | function GG(a, b, c, d, x, s, t) {
1032 | var n = a + ((b & d) | (c & ~d)) + x + t;
1033 | return ((n << s) | (n >>> (32 - s))) + b;
1034 | }
1035 |
1036 | function HH(a, b, c, d, x, s, t) {
1037 | var n = a + (b ^ c ^ d) + x + t;
1038 | return ((n << s) | (n >>> (32 - s))) + b;
1039 | }
1040 |
1041 | function II(a, b, c, d, x, s, t) {
1042 | var n = a + (c ^ (b | ~d)) + x + t;
1043 | return ((n << s) | (n >>> (32 - s))) + b;
1044 | }
1045 |
1046 | /**
1047 | * Shortcut function to the hasher's object interface.
1048 | *
1049 | * @param {WordArray|string} message The message to hash.
1050 | *
1051 | * @return {WordArray} The hash.
1052 | *
1053 | * @static
1054 | *
1055 | * @example
1056 | *
1057 | * var hash = CryptoJS.MD5('message');
1058 | * var hash = CryptoJS.MD5(wordArray);
1059 | */
1060 | C.MD5 = Hasher._createHelper(MD5);
1061 |
1062 | /**
1063 | * Shortcut function to the HMAC's object interface.
1064 | *
1065 | * @param {WordArray|string} message The message to hash.
1066 | * @param {WordArray|string} key The secret key.
1067 | *
1068 | * @return {WordArray} The HMAC.
1069 | *
1070 | * @static
1071 | *
1072 | * @example
1073 | *
1074 | * var hmac = CryptoJS.HmacMD5(message, key);
1075 | */
1076 | C.HmacMD5 = Hasher._createHmacHelper(MD5);
1077 | }(Math));
1078 |
1079 | /*
1080 | CryptoJS v3.1.2
1081 | code.google.com/p/crypto-js
1082 | (c) 2009-2013 by Jeff Mott. All rights reserved.
1083 | code.google.com/p/crypto-js/wiki/License
1084 | */
1085 | (function () {
1086 | // Shortcuts
1087 | var C = CryptoJS;
1088 | var C_lib = C.lib;
1089 | var Base = C_lib.Base;
1090 | var WordArray = C_lib.WordArray;
1091 | var C_algo = C.algo;
1092 | var MD5 = C_algo.MD5;
1093 |
1094 | /**
1095 | * This key derivation function is meant to conform with EVP_BytesToKey.
1096 | * www.openssl.org/docs/crypto/EVP_BytesToKey.html
1097 | */
1098 | var EvpKDF = C_algo.EvpKDF = Base.extend({
1099 | /**
1100 | * Configuration options.
1101 | *
1102 | * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
1103 | * @property {Hasher} hasher The hash algorithm to use. Default: MD5
1104 | * @property {number} iterations The number of iterations to perform. Default: 1
1105 | */
1106 | cfg: Base.extend({
1107 | keySize: 128/32,
1108 | hasher: MD5,
1109 | iterations: 1
1110 | }),
1111 |
1112 | /**
1113 | * Initializes a newly created key derivation function.
1114 | *
1115 | * @param {Object} cfg (Optional) The configuration options to use for the derivation.
1116 | *
1117 | * @example
1118 | *
1119 | * var kdf = CryptoJS.algo.EvpKDF.create();
1120 | * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
1121 | * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
1122 | */
1123 | init: function (cfg) {
1124 | this.cfg = this.cfg.extend(cfg);
1125 | },
1126 |
1127 | /**
1128 | * Derives a key from a password.
1129 | *
1130 | * @param {WordArray|string} password The password.
1131 | * @param {WordArray|string} salt A salt.
1132 | *
1133 | * @return {WordArray} The derived key.
1134 | *
1135 | * @example
1136 | *
1137 | * var key = kdf.compute(password, salt);
1138 | */
1139 | compute: function (password, salt) {
1140 | // Shortcut
1141 | var cfg = this.cfg;
1142 |
1143 | // Init hasher
1144 | var hasher = cfg.hasher.create();
1145 |
1146 | // Initial values
1147 | var derivedKey = WordArray.create();
1148 |
1149 | // Shortcuts
1150 | var derivedKeyWords = derivedKey.words;
1151 | var keySize = cfg.keySize;
1152 | var iterations = cfg.iterations;
1153 |
1154 | // Generate key
1155 | while (derivedKeyWords.length < keySize) {
1156 | if (block) {
1157 | hasher.update(block);
1158 | }
1159 | var block = hasher.update(password).finalize(salt);
1160 | hasher.reset();
1161 |
1162 | // Iterations
1163 | for (var i = 1; i < iterations; i++) {
1164 | block = hasher.finalize(block);
1165 | hasher.reset();
1166 | }
1167 |
1168 | derivedKey.concat(block);
1169 | }
1170 | derivedKey.sigBytes = keySize * 4;
1171 |
1172 | return derivedKey;
1173 | }
1174 | });
1175 |
1176 | /**
1177 | * Derives a key from a password.
1178 | *
1179 | * @param {WordArray|string} password The password.
1180 | * @param {WordArray|string} salt A salt.
1181 | * @param {Object} cfg (Optional) The configuration options to use for this computation.
1182 | *
1183 | * @return {WordArray} The derived key.
1184 | *
1185 | * @static
1186 | *
1187 | * @example
1188 | *
1189 | * var key = CryptoJS.EvpKDF(password, salt);
1190 | * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
1191 | * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
1192 | */
1193 | C.EvpKDF = function (password, salt, cfg) {
1194 | return EvpKDF.create(cfg).compute(password, salt);
1195 | };
1196 | }());
1197 |
1198 |
1199 | /*
1200 | CryptoJS v3.1.2
1201 | code.google.com/p/crypto-js
1202 | (c) 2009-2013 by Jeff Mott. All rights reserved.
1203 | code.google.com/p/crypto-js/wiki/License
1204 | */
1205 | /**
1206 | * Cipher core components.
1207 | */
1208 | CryptoJS.lib.Cipher || (function (undefined) {
1209 | // Shortcuts
1210 | var C = CryptoJS;
1211 | var C_lib = C.lib;
1212 | var Base = C_lib.Base;
1213 | var WordArray = C_lib.WordArray;
1214 | var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
1215 | var C_enc = C.enc;
1216 | var Utf8 = C_enc.Utf8;
1217 | var Base64 = C_enc.Base64;
1218 | var C_algo = C.algo;
1219 | var EvpKDF = C_algo.EvpKDF;
1220 |
1221 | /**
1222 | * Abstract base cipher template.
1223 | *
1224 | * @property {number} keySize This cipher's key size. Default: 4 (128 bits)
1225 | * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
1226 | * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
1227 | * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
1228 | */
1229 | var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
1230 | /**
1231 | * Configuration options.
1232 | *
1233 | * @property {WordArray} iv The IV to use for this operation.
1234 | */
1235 | cfg: Base.extend(),
1236 |
1237 | /**
1238 | * Creates this cipher in encryption mode.
1239 | *
1240 | * @param {WordArray} key The key.
1241 | * @param {Object} cfg (Optional) The configuration options to use for this operation.
1242 | *
1243 | * @return {Cipher} A cipher instance.
1244 | *
1245 | * @static
1246 | *
1247 | * @example
1248 | *
1249 | * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
1250 | */
1251 | createEncryptor: function (key, cfg) {
1252 | return this.create(this._ENC_XFORM_MODE, key, cfg);
1253 | },
1254 |
1255 | /**
1256 | * Creates this cipher in decryption mode.
1257 | *
1258 | * @param {WordArray} key The key.
1259 | * @param {Object} cfg (Optional) The configuration options to use for this operation.
1260 | *
1261 | * @return {Cipher} A cipher instance.
1262 | *
1263 | * @static
1264 | *
1265 | * @example
1266 | *
1267 | * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
1268 | */
1269 | createDecryptor: function (key, cfg) {
1270 | return this.create(this._DEC_XFORM_MODE, key, cfg);
1271 | },
1272 |
1273 | /**
1274 | * Initializes a newly created cipher.
1275 | *
1276 | * @param {number} xformMode Either the encryption or decryption transormation mode constant.
1277 | * @param {WordArray} key The key.
1278 | * @param {Object} cfg (Optional) The configuration options to use for this operation.
1279 | *
1280 | * @example
1281 | *
1282 | * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
1283 | */
1284 | init: function (xformMode, key, cfg) {
1285 | // Apply config defaults
1286 | this.cfg = this.cfg.extend(cfg);
1287 |
1288 | // Store transform mode and key
1289 | this._xformMode = xformMode;
1290 | this._key = key;
1291 |
1292 | // Set initial values
1293 | this.reset();
1294 | },
1295 |
1296 | /**
1297 | * Resets this cipher to its initial state.
1298 | *
1299 | * @example
1300 | *
1301 | * cipher.reset();
1302 | */
1303 | reset: function () {
1304 | // Reset data buffer
1305 | BufferedBlockAlgorithm.reset.call(this);
1306 |
1307 | // Perform concrete-cipher logic
1308 | this._doReset();
1309 | },
1310 |
1311 | /**
1312 | * Adds data to be encrypted or decrypted.
1313 | *
1314 | * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
1315 | *
1316 | * @return {WordArray} The data after processing.
1317 | *
1318 | * @example
1319 | *
1320 | * var encrypted = cipher.process('data');
1321 | * var encrypted = cipher.process(wordArray);
1322 | */
1323 | process: function (dataUpdate) {
1324 | // Append
1325 | this._append(dataUpdate);
1326 |
1327 | // Process available blocks
1328 | return this._process();
1329 | },
1330 |
1331 | /**
1332 | * Finalizes the encryption or decryption process.
1333 | * Note that the finalize operation is effectively a destructive, read-once operation.
1334 | *
1335 | * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
1336 | *
1337 | * @return {WordArray} The data after final processing.
1338 | *
1339 | * @example
1340 | *
1341 | * var encrypted = cipher.finalize();
1342 | * var encrypted = cipher.finalize('data');
1343 | * var encrypted = cipher.finalize(wordArray);
1344 | */
1345 | finalize: function (dataUpdate) {
1346 | // Final data update
1347 | if (dataUpdate) {
1348 | this._append(dataUpdate);
1349 | }
1350 |
1351 | // Perform concrete-cipher logic
1352 | var finalProcessedData = this._doFinalize();
1353 |
1354 | return finalProcessedData;
1355 | },
1356 |
1357 | keySize: 128/32,
1358 |
1359 | ivSize: 128/32,
1360 |
1361 | _ENC_XFORM_MODE: 1,
1362 |
1363 | _DEC_XFORM_MODE: 2,
1364 |
1365 | /**
1366 | * Creates shortcut functions to a cipher's object interface.
1367 | *
1368 | * @param {Cipher} cipher The cipher to create a helper for.
1369 | *
1370 | * @return {Object} An object with encrypt and decrypt shortcut functions.
1371 | *
1372 | * @static
1373 | *
1374 | * @example
1375 | *
1376 | * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
1377 | */
1378 | _createHelper: (function () {
1379 | function selectCipherStrategy(key) {
1380 | if (typeof key == 'string') {
1381 | return PasswordBasedCipher;
1382 | } else {
1383 | return SerializableCipher;
1384 | }
1385 | }
1386 |
1387 | return function (cipher) {
1388 | return {
1389 | encrypt: function (message, key, cfg) {
1390 | return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
1391 | },
1392 |
1393 | decrypt: function (ciphertext, key, cfg) {
1394 | return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
1395 | }
1396 | };
1397 | };
1398 | }())
1399 | });
1400 |
1401 | /**
1402 | * Abstract base stream cipher template.
1403 | *
1404 | * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
1405 | */
1406 | var StreamCipher = C_lib.StreamCipher = Cipher.extend({
1407 | _doFinalize: function () {
1408 | // Process partial blocks
1409 | var finalProcessedBlocks = this._process(!!'flush');
1410 |
1411 | return finalProcessedBlocks;
1412 | },
1413 |
1414 | blockSize: 1
1415 | });
1416 |
1417 | /**
1418 | * Mode namespace.
1419 | */
1420 | var C_mode = C.mode = {};
1421 |
1422 | /**
1423 | * Abstract base block cipher mode template.
1424 | */
1425 | var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
1426 | /**
1427 | * Creates this mode for encryption.
1428 | *
1429 | * @param {Cipher} cipher A block cipher instance.
1430 | * @param {Array} iv The IV words.
1431 | *
1432 | * @static
1433 | *
1434 | * @example
1435 | *
1436 | * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
1437 | */
1438 | createEncryptor: function (cipher, iv) {
1439 | return this.Encryptor.create(cipher, iv);
1440 | },
1441 |
1442 | /**
1443 | * Creates this mode for decryption.
1444 | *
1445 | * @param {Cipher} cipher A block cipher instance.
1446 | * @param {Array} iv The IV words.
1447 | *
1448 | * @static
1449 | *
1450 | * @example
1451 | *
1452 | * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
1453 | */
1454 | createDecryptor: function (cipher, iv) {
1455 | return this.Decryptor.create(cipher, iv);
1456 | },
1457 |
1458 | /**
1459 | * Initializes a newly created mode.
1460 | *
1461 | * @param {Cipher} cipher A block cipher instance.
1462 | * @param {Array} iv The IV words.
1463 | *
1464 | * @example
1465 | *
1466 | * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
1467 | */
1468 | init: function (cipher, iv) {
1469 | this._cipher = cipher;
1470 | this._iv = iv;
1471 | }
1472 | });
1473 |
1474 | /**
1475 | * Cipher Block Chaining mode.
1476 | */
1477 | var CBC = C_mode.CBC = (function () {
1478 | /**
1479 | * Abstract base CBC mode.
1480 | */
1481 | var CBC = BlockCipherMode.extend();
1482 |
1483 | /**
1484 | * CBC encryptor.
1485 | */
1486 | CBC.Encryptor = CBC.extend({
1487 | /**
1488 | * Processes the data block at offset.
1489 | *
1490 | * @param {Array} words The data words to operate on.
1491 | * @param {number} offset The offset where the block starts.
1492 | *
1493 | * @example
1494 | *
1495 | * mode.processBlock(data.words, offset);
1496 | */
1497 | processBlock: function (words, offset) {
1498 | // Shortcuts
1499 | var cipher = this._cipher;
1500 | var blockSize = cipher.blockSize;
1501 |
1502 | // XOR and encrypt
1503 | xorBlock.call(this, words, offset, blockSize);
1504 | cipher.encryptBlock(words, offset);
1505 |
1506 | // Remember this block to use with next block
1507 | this._prevBlock = words.slice(offset, offset + blockSize);
1508 | }
1509 | });
1510 |
1511 | /**
1512 | * CBC decryptor.
1513 | */
1514 | CBC.Decryptor = CBC.extend({
1515 | /**
1516 | * Processes the data block at offset.
1517 | *
1518 | * @param {Array} words The data words to operate on.
1519 | * @param {number} offset The offset where the block starts.
1520 | *
1521 | * @example
1522 | *
1523 | * mode.processBlock(data.words, offset);
1524 | */
1525 | processBlock: function (words, offset) {
1526 | // Shortcuts
1527 | var cipher = this._cipher;
1528 | var blockSize = cipher.blockSize;
1529 |
1530 | // Remember this block to use with next block
1531 | var thisBlock = words.slice(offset, offset + blockSize);
1532 |
1533 | // Decrypt and XOR
1534 | cipher.decryptBlock(words, offset);
1535 | xorBlock.call(this, words, offset, blockSize);
1536 |
1537 | // This block becomes the previous block
1538 | this._prevBlock = thisBlock;
1539 | }
1540 | });
1541 |
1542 | function xorBlock(words, offset, blockSize) {
1543 | // Shortcut
1544 | var iv = this._iv;
1545 |
1546 | // Choose mixing block
1547 | if (iv) {
1548 | var block = iv;
1549 |
1550 | // Remove IV for subsequent blocks
1551 | this._iv = undefined;
1552 | } else {
1553 | var block = this._prevBlock;
1554 | }
1555 |
1556 | // XOR blocks
1557 | for (var i = 0; i < blockSize; i++) {
1558 | words[offset + i] ^= block[i];
1559 | }
1560 | }
1561 |
1562 | return CBC;
1563 | }());
1564 |
1565 | /**
1566 | * Padding namespace.
1567 | */
1568 | var C_pad = C.pad = {};
1569 |
1570 | /**
1571 | * PKCS #5/7 padding strategy.
1572 | */
1573 | var Pkcs7 = C_pad.Pkcs7 = {
1574 | /**
1575 | * Pads data using the algorithm defined in PKCS #5/7.
1576 | *
1577 | * @param {WordArray} data The data to pad.
1578 | * @param {number} blockSize The multiple that the data should be padded to.
1579 | *
1580 | * @static
1581 | *
1582 | * @example
1583 | *
1584 | * CryptoJS.pad.Pkcs7.pad(wordArray, 4);
1585 | */
1586 | pad: function (data, blockSize) {
1587 | // Shortcut
1588 | var blockSizeBytes = blockSize * 4;
1589 |
1590 | // Count padding bytes
1591 | var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
1592 |
1593 | // Create padding word
1594 | var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
1595 |
1596 | // Create padding
1597 | var paddingWords = [];
1598 | for (var i = 0; i < nPaddingBytes; i += 4) {
1599 | paddingWords.push(paddingWord);
1600 | }
1601 | var padding = WordArray.create(paddingWords, nPaddingBytes);
1602 |
1603 | // Add padding
1604 | data.concat(padding);
1605 | },
1606 |
1607 | /**
1608 | * Unpads data that had been padded using the algorithm defined in PKCS #5/7.
1609 | *
1610 | * @param {WordArray} data The data to unpad.
1611 | *
1612 | * @static
1613 | *
1614 | * @example
1615 | *
1616 | * CryptoJS.pad.Pkcs7.unpad(wordArray);
1617 | */
1618 | unpad: function (data) {
1619 | // Get number of padding bytes from last byte
1620 | var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
1621 |
1622 | // Remove padding
1623 | data.sigBytes -= nPaddingBytes;
1624 | }
1625 | };
1626 |
1627 | /**
1628 | * Abstract base block cipher template.
1629 | *
1630 | * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
1631 | */
1632 | var BlockCipher = C_lib.BlockCipher = Cipher.extend({
1633 | /**
1634 | * Configuration options.
1635 | *
1636 | * @property {Mode} mode The block mode to use. Default: CBC
1637 | * @property {Padding} padding The padding strategy to use. Default: Pkcs7
1638 | */
1639 | cfg: Cipher.cfg.extend({
1640 | mode: CBC,
1641 | padding: Pkcs7
1642 | }),
1643 |
1644 | reset: function () {
1645 | // Reset cipher
1646 | Cipher.reset.call(this);
1647 |
1648 | // Shortcuts
1649 | var cfg = this.cfg;
1650 | var iv = cfg.iv;
1651 | var mode = cfg.mode;
1652 |
1653 | // Reset block mode
1654 | if (this._xformMode == this._ENC_XFORM_MODE) {
1655 | var modeCreator = mode.createEncryptor;
1656 | } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
1657 | var modeCreator = mode.createDecryptor;
1658 |
1659 | // Keep at least one block in the buffer for unpadding
1660 | this._minBufferSize = 1;
1661 | }
1662 | this._mode = modeCreator.call(mode, this, iv && iv.words);
1663 | },
1664 |
1665 | _doProcessBlock: function (words, offset) {
1666 | this._mode.processBlock(words, offset);
1667 | },
1668 |
1669 | _doFinalize: function () {
1670 | // Shortcut
1671 | var padding = this.cfg.padding;
1672 |
1673 | // Finalize
1674 | if (this._xformMode == this._ENC_XFORM_MODE) {
1675 | // Pad data
1676 | padding.pad(this._data, this.blockSize);
1677 |
1678 | // Process final blocks
1679 | var finalProcessedBlocks = this._process(!!'flush');
1680 | } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
1681 | // Process final blocks
1682 | var finalProcessedBlocks = this._process(!!'flush');
1683 |
1684 | // Unpad data
1685 | padding.unpad(finalProcessedBlocks);
1686 | }
1687 |
1688 | return finalProcessedBlocks;
1689 | },
1690 |
1691 | blockSize: 128/32
1692 | });
1693 |
1694 | /**
1695 | * A collection of cipher parameters.
1696 | *
1697 | * @property {WordArray} ciphertext The raw ciphertext.
1698 | * @property {WordArray} key The key to this ciphertext.
1699 | * @property {WordArray} iv The IV used in the ciphering operation.
1700 | * @property {WordArray} salt The salt used with a key derivation function.
1701 | * @property {Cipher} algorithm The cipher algorithm.
1702 | * @property {Mode} mode The block mode used in the ciphering operation.
1703 | * @property {Padding} padding The padding scheme used in the ciphering operation.
1704 | * @property {number} blockSize The block size of the cipher.
1705 | * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
1706 | */
1707 | var CipherParams = C_lib.CipherParams = Base.extend({
1708 | /**
1709 | * Initializes a newly created cipher params object.
1710 | *
1711 | * @param {Object} cipherParams An object with any of the possible cipher parameters.
1712 | *
1713 | * @example
1714 | *
1715 | * var cipherParams = CryptoJS.lib.CipherParams.create({
1716 | * ciphertext: ciphertextWordArray,
1717 | * key: keyWordArray,
1718 | * iv: ivWordArray,
1719 | * salt: saltWordArray,
1720 | * algorithm: CryptoJS.algo.AES,
1721 | * mode: CryptoJS.mode.CBC,
1722 | * padding: CryptoJS.pad.PKCS7,
1723 | * blockSize: 4,
1724 | * formatter: CryptoJS.format.OpenSSL
1725 | * });
1726 | */
1727 | init: function (cipherParams) {
1728 | this.mixIn(cipherParams);
1729 | },
1730 |
1731 | /**
1732 | * Converts this cipher params object to a string.
1733 | *
1734 | * @param {Format} formatter (Optional) The formatting strategy to use.
1735 | *
1736 | * @return {string} The stringified cipher params.
1737 | *
1738 | * @throws Error If neither the formatter nor the default formatter is set.
1739 | *
1740 | * @example
1741 | *
1742 | * var string = cipherParams + '';
1743 | * var string = cipherParams.toString();
1744 | * var string = cipherParams.toString(CryptoJS.format.OpenSSL);
1745 | */
1746 | toString: function (formatter) {
1747 | return (formatter || this.formatter).stringify(this);
1748 | }
1749 | });
1750 |
1751 | /**
1752 | * Format namespace.
1753 | */
1754 | var C_format = C.format = {};
1755 |
1756 | /**
1757 | * OpenSSL formatting strategy.
1758 | */
1759 | var OpenSSLFormatter = C_format.OpenSSL = {
1760 | /**
1761 | * Converts a cipher params object to an OpenSSL-compatible string.
1762 | *
1763 | * @param {CipherParams} cipherParams The cipher params object.
1764 | *
1765 | * @return {string} The OpenSSL-compatible string.
1766 | *
1767 | * @static
1768 | *
1769 | * @example
1770 | *
1771 | * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
1772 | */
1773 | stringify: function (cipherParams) {
1774 | // Shortcuts
1775 | var ciphertext = cipherParams.ciphertext;
1776 | var salt = cipherParams.salt;
1777 |
1778 | // Format
1779 | if (salt) {
1780 | var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
1781 | } else {
1782 | var wordArray = ciphertext;
1783 | }
1784 |
1785 | return wordArray.toString(Base64);
1786 | },
1787 |
1788 | /**
1789 | * Converts an OpenSSL-compatible string to a cipher params object.
1790 | *
1791 | * @param {string} openSSLStr The OpenSSL-compatible string.
1792 | *
1793 | * @return {CipherParams} The cipher params object.
1794 | *
1795 | * @static
1796 | *
1797 | * @example
1798 | *
1799 | * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
1800 | */
1801 | parse: function (openSSLStr) {
1802 | // Parse base64
1803 | var ciphertext = Base64.parse(openSSLStr);
1804 |
1805 | // Shortcut
1806 | var ciphertextWords = ciphertext.words;
1807 |
1808 | // Test for salt
1809 | if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
1810 | // Extract salt
1811 | var salt = WordArray.create(ciphertextWords.slice(2, 4));
1812 |
1813 | // Remove salt from ciphertext
1814 | ciphertextWords.splice(0, 4);
1815 | ciphertext.sigBytes -= 16;
1816 | }
1817 |
1818 | return CipherParams.create({ ciphertext: ciphertext, salt: salt });
1819 | }
1820 | };
1821 |
1822 | /**
1823 | * A cipher wrapper that returns ciphertext as a serializable cipher params object.
1824 | */
1825 | var SerializableCipher = C_lib.SerializableCipher = Base.extend({
1826 | /**
1827 | * Configuration options.
1828 | *
1829 | * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
1830 | */
1831 | cfg: Base.extend({
1832 | format: OpenSSLFormatter
1833 | }),
1834 |
1835 | /**
1836 | * Encrypts a message.
1837 | *
1838 | * @param {Cipher} cipher The cipher algorithm to use.
1839 | * @param {WordArray|string} message The message to encrypt.
1840 | * @param {WordArray} key The key.
1841 | * @param {Object} cfg (Optional) The configuration options to use for this operation.
1842 | *
1843 | * @return {CipherParams} A cipher params object.
1844 | *
1845 | * @static
1846 | *
1847 | * @example
1848 | *
1849 | * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
1850 | * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
1851 | * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
1852 | */
1853 | encrypt: function (cipher, message, key, cfg) {
1854 | // Apply config defaults
1855 | cfg = this.cfg.extend(cfg);
1856 |
1857 | // Encrypt
1858 | var encryptor = cipher.createEncryptor(key, cfg);
1859 | var ciphertext = encryptor.finalize(message);
1860 |
1861 | // Shortcut
1862 | var cipherCfg = encryptor.cfg;
1863 |
1864 | // Create and return serializable cipher params
1865 | return CipherParams.create({
1866 | ciphertext: ciphertext,
1867 | key: key,
1868 | iv: cipherCfg.iv,
1869 | algorithm: cipher,
1870 | mode: cipherCfg.mode,
1871 | padding: cipherCfg.padding,
1872 | blockSize: cipher.blockSize,
1873 | formatter: cfg.format
1874 | });
1875 | },
1876 |
1877 | /**
1878 | * Decrypts serialized ciphertext.
1879 | *
1880 | * @param {Cipher} cipher The cipher algorithm to use.
1881 | * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
1882 | * @param {WordArray} key The key.
1883 | * @param {Object} cfg (Optional) The configuration options to use for this operation.
1884 | *
1885 | * @return {WordArray} The plaintext.
1886 | *
1887 | * @static
1888 | *
1889 | * @example
1890 | *
1891 | * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
1892 | * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
1893 | */
1894 | decrypt: function (cipher, ciphertext, key, cfg) {
1895 | // Apply config defaults
1896 | cfg = this.cfg.extend(cfg);
1897 |
1898 | // Convert string to CipherParams
1899 | ciphertext = this._parse(ciphertext, cfg.format);
1900 |
1901 | // Decrypt
1902 | var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
1903 |
1904 | return plaintext;
1905 | },
1906 |
1907 | /**
1908 | * Converts serialized ciphertext to CipherParams,
1909 | * else assumed CipherParams already and returns ciphertext unchanged.
1910 | *
1911 | * @param {CipherParams|string} ciphertext The ciphertext.
1912 | * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
1913 | *
1914 | * @return {CipherParams} The unserialized ciphertext.
1915 | *
1916 | * @static
1917 | *
1918 | * @example
1919 | *
1920 | * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
1921 | */
1922 | _parse: function (ciphertext, format) {
1923 | if (typeof ciphertext == 'string') {
1924 | return format.parse(ciphertext, this);
1925 | } else {
1926 | return ciphertext;
1927 | }
1928 | }
1929 | });
1930 |
1931 | /**
1932 | * Key derivation function namespace.
1933 | */
1934 | var C_kdf = C.kdf = {};
1935 |
1936 | /**
1937 | * OpenSSL key derivation function.
1938 | */
1939 | var OpenSSLKdf = C_kdf.OpenSSL = {
1940 | /**
1941 | * Derives a key and IV from a password.
1942 | *
1943 | * @param {string} password The password to derive from.
1944 | * @param {number} keySize The size in words of the key to generate.
1945 | * @param {number} ivSize The size in words of the IV to generate.
1946 | * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
1947 | *
1948 | * @return {CipherParams} A cipher params object with the key, IV, and salt.
1949 | *
1950 | * @static
1951 | *
1952 | * @example
1953 | *
1954 | * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
1955 | * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
1956 | */
1957 | execute: function (password, keySize, ivSize, salt) {
1958 | // Generate random salt
1959 | if (!salt) {
1960 | salt = WordArray.random(64/8);
1961 | }
1962 |
1963 | // Derive key and IV
1964 | var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
1965 |
1966 | // Separate key and IV
1967 | var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
1968 | key.sigBytes = keySize * 4;
1969 |
1970 | // Return params
1971 | return CipherParams.create({ key: key, iv: iv, salt: salt });
1972 | }
1973 | };
1974 |
1975 | /**
1976 | * A serializable cipher wrapper that derives the key from a password,
1977 | * and returns ciphertext as a serializable cipher params object.
1978 | */
1979 | var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
1980 | /**
1981 | * Configuration options.
1982 | *
1983 | * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
1984 | */
1985 | cfg: SerializableCipher.cfg.extend({
1986 | kdf: OpenSSLKdf
1987 | }),
1988 |
1989 | /**
1990 | * Encrypts a message using a password.
1991 | *
1992 | * @param {Cipher} cipher The cipher algorithm to use.
1993 | * @param {WordArray|string} message The message to encrypt.
1994 | * @param {string} password The password.
1995 | * @param {Object} cfg (Optional) The configuration options to use for this operation.
1996 | *
1997 | * @return {CipherParams} A cipher params object.
1998 | *
1999 | * @static
2000 | *
2001 | * @example
2002 | *
2003 | * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
2004 | * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
2005 | */
2006 | encrypt: function (cipher, message, password, cfg) {
2007 | // Apply config defaults
2008 | cfg = this.cfg.extend(cfg);
2009 |
2010 | // Derive key and other params
2011 | var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
2012 |
2013 | // Add IV to config
2014 | cfg.iv = derivedParams.iv;
2015 |
2016 | // Encrypt
2017 | var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
2018 |
2019 | // Mix in derived params
2020 | ciphertext.mixIn(derivedParams);
2021 |
2022 | return ciphertext;
2023 | },
2024 |
2025 | /**
2026 | * Decrypts serialized ciphertext using a password.
2027 | *
2028 | * @param {Cipher} cipher The cipher algorithm to use.
2029 | * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
2030 | * @param {string} password The password.
2031 | * @param {Object} cfg (Optional) The configuration options to use for this operation.
2032 | *
2033 | * @return {WordArray} The plaintext.
2034 | *
2035 | * @static
2036 | *
2037 | * @example
2038 | *
2039 | * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
2040 | * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
2041 | */
2042 | decrypt: function (cipher, ciphertext, password, cfg) {
2043 | // Apply config defaults
2044 | cfg = this.cfg.extend(cfg);
2045 |
2046 | // Convert string to CipherParams
2047 | ciphertext = this._parse(ciphertext, cfg.format);
2048 |
2049 | // Derive key and other params
2050 | var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
2051 |
2052 | // Add IV to config
2053 | cfg.iv = derivedParams.iv;
2054 |
2055 | // Decrypt
2056 | var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
2057 |
2058 | return plaintext;
2059 | }
2060 | });
2061 | }());
2062 |
2063 | /*
2064 | CryptoJS v3.1.2
2065 | code.google.com/p/crypto-js
2066 | (c) 2009-2013 by Jeff Mott. All rights reserved.
2067 | code.google.com/p/crypto-js/wiki/License
2068 | */
2069 | (function () {
2070 | // Shortcuts
2071 | var C = CryptoJS;
2072 | var C_lib = C.lib;
2073 | var BlockCipher = C_lib.BlockCipher;
2074 | var C_algo = C.algo;
2075 |
2076 | // Lookup tables
2077 | var SBOX = [];
2078 | var INV_SBOX = [];
2079 | var SUB_MIX_0 = [];
2080 | var SUB_MIX_1 = [];
2081 | var SUB_MIX_2 = [];
2082 | var SUB_MIX_3 = [];
2083 | var INV_SUB_MIX_0 = [];
2084 | var INV_SUB_MIX_1 = [];
2085 | var INV_SUB_MIX_2 = [];
2086 | var INV_SUB_MIX_3 = [];
2087 |
2088 | // Compute lookup tables
2089 | (function () {
2090 | // Compute double table
2091 | var d = [];
2092 | for (var i = 0; i < 256; i++) {
2093 | if (i < 128) {
2094 | d[i] = i << 1;
2095 | } else {
2096 | d[i] = (i << 1) ^ 0x11b;
2097 | }
2098 | }
2099 |
2100 | // Walk GF(2^8)
2101 | var x = 0;
2102 | var xi = 0;
2103 | for (var i = 0; i < 256; i++) {
2104 | // Compute sbox
2105 | var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
2106 | sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
2107 | SBOX[x] = sx;
2108 | INV_SBOX[sx] = x;
2109 |
2110 | // Compute multiplication
2111 | var x2 = d[x];
2112 | var x4 = d[x2];
2113 | var x8 = d[x4];
2114 |
2115 | // Compute sub bytes, mix columns tables
2116 | var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
2117 | SUB_MIX_0[x] = (t << 24) | (t >>> 8);
2118 | SUB_MIX_1[x] = (t << 16) | (t >>> 16);
2119 | SUB_MIX_2[x] = (t << 8) | (t >>> 24);
2120 | SUB_MIX_3[x] = t;
2121 |
2122 | // Compute inv sub bytes, inv mix columns tables
2123 | var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
2124 | INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
2125 | INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
2126 | INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24);
2127 | INV_SUB_MIX_3[sx] = t;
2128 |
2129 | // Compute next counter
2130 | if (!x) {
2131 | x = xi = 1;
2132 | } else {
2133 | x = x2 ^ d[d[d[x8 ^ x2]]];
2134 | xi ^= d[d[xi]];
2135 | }
2136 | }
2137 | }());
2138 |
2139 | // Precomputed Rcon lookup
2140 | var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
2141 |
2142 | /**
2143 | * AES block cipher algorithm.
2144 | */
2145 | var AES = C_algo.AES = BlockCipher.extend({
2146 | _doReset: function () {
2147 | // Shortcuts
2148 | var key = this._key;
2149 | var keyWords = key.words;
2150 | var keySize = key.sigBytes / 4;
2151 |
2152 | // Compute number of rounds
2153 | var nRounds = this._nRounds = keySize + 6
2154 |
2155 | // Compute number of key schedule rows
2156 | var ksRows = (nRounds + 1) * 4;
2157 |
2158 | // Compute key schedule
2159 | var keySchedule = this._keySchedule = [];
2160 | for (var ksRow = 0; ksRow < ksRows; ksRow++) {
2161 | if (ksRow < keySize) {
2162 | keySchedule[ksRow] = keyWords[ksRow];
2163 | } else {
2164 | var t = keySchedule[ksRow - 1];
2165 |
2166 | if (!(ksRow % keySize)) {
2167 | // Rot word
2168 | t = (t << 8) | (t >>> 24);
2169 |
2170 | // Sub word
2171 | t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
2172 |
2173 | // Mix Rcon
2174 | t ^= RCON[(ksRow / keySize) | 0] << 24;
2175 | } else if (keySize > 6 && ksRow % keySize == 4) {
2176 | // Sub word
2177 | t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
2178 | }
2179 |
2180 | keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
2181 | }
2182 | }
2183 |
2184 | // Compute inv key schedule
2185 | var invKeySchedule = this._invKeySchedule = [];
2186 | for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
2187 | var ksRow = ksRows - invKsRow;
2188 |
2189 | if (invKsRow % 4) {
2190 | var t = keySchedule[ksRow];
2191 | } else {
2192 | var t = keySchedule[ksRow - 4];
2193 | }
2194 |
2195 | if (invKsRow < 4 || ksRow <= 4) {
2196 | invKeySchedule[invKsRow] = t;
2197 | } else {
2198 | invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
2199 | INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
2200 | }
2201 | }
2202 | },
2203 |
2204 | encryptBlock: function (M, offset) {
2205 | this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
2206 | },
2207 |
2208 | decryptBlock: function (M, offset) {
2209 | // Swap 2nd and 4th rows
2210 | var t = M[offset + 1];
2211 | M[offset + 1] = M[offset + 3];
2212 | M[offset + 3] = t;
2213 |
2214 | this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
2215 |
2216 | // Inv swap 2nd and 4th rows
2217 | var t = M[offset + 1];
2218 | M[offset + 1] = M[offset + 3];
2219 | M[offset + 3] = t;
2220 | },
2221 |
2222 | _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
2223 | // Shortcut
2224 | var nRounds = this._nRounds;
2225 |
2226 | // Get input, add round key
2227 | var s0 = M[offset] ^ keySchedule[0];
2228 | var s1 = M[offset + 1] ^ keySchedule[1];
2229 | var s2 = M[offset + 2] ^ keySchedule[2];
2230 | var s3 = M[offset + 3] ^ keySchedule[3];
2231 |
2232 | // Key schedule row counter
2233 | var ksRow = 4;
2234 |
2235 | // Rounds
2236 | for (var round = 1; round < nRounds; round++) {
2237 | // Shift rows, sub bytes, mix columns, add round key
2238 | var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
2239 | var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
2240 | var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
2241 | var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
2242 |
2243 | // Update state
2244 | s0 = t0;
2245 | s1 = t1;
2246 | s2 = t2;
2247 | s3 = t3;
2248 | }
2249 |
2250 | // Shift rows, sub bytes, add round key
2251 | var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
2252 | var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
2253 | var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
2254 | var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
2255 |
2256 | // Set output
2257 | M[offset] = t0;
2258 | M[offset + 1] = t1;
2259 | M[offset + 2] = t2;
2260 | M[offset + 3] = t3;
2261 | },
2262 |
2263 | keySize: 256/32
2264 | });
2265 |
2266 | /**
2267 | * Shortcut functions to the cipher's object interface.
2268 | *
2269 | * @example
2270 | *
2271 | * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
2272 | * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg);
2273 | */
2274 | C.AES = BlockCipher._createHelper(AES);
2275 | }());
2276 |
2277 |
2278 |
--------------------------------------------------------------------------------