1 /* crypto-2.1.0.js (c) 2013-2024 Kenji Urushima | kjur.github.io/jsrsasign/license
  2  */
  3 /*
  4  * crypto.js - Cryptographic Algorithm Provider class
  5  *
  6  * Copyright (c) 2013-2024 Kenji Urushima (kenji.urushima@gmail.com)
  7  *
  8  * This software is licensed under the terms of the MIT License.
  9  * https://kjur.github.io/jsrsasign/license
 10  *
 11  * The above copyright and license notice shall be 
 12  * included in all copies or substantial portions of the Software.
 13  */
 14 
 15 /**
 16  * @fileOverview
 17  * @name crypto-1.1.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version jsrsasign 11.1.0 crypto 2.1.0 (2024-Feb-01)
 20  * @since jsrsasign 2.2
 21  * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
 22  */
 23 
 24 /** 
 25  * kjur's class library name space
 26  * @name KJUR
 27  * @namespace kjur's class library name space
 28  */
 29 if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
 30 /**
 31  * kjur's cryptographic algorithm provider library name space
 32  * <p>
 33  * This namespace privides following crytpgrahic classes.
 34  * <ul>
 35  * <li>{@link KJUR.crypto.MessageDigest} - Java JCE(cryptograhic extension) style MessageDigest class</li>
 36  * <li>{@link KJUR.crypto.Signature} - Java JCE(cryptograhic extension) style Signature class</li>
 37  * <li>{@link KJUR.crypto.Util} - cryptographic utility functions and properties</li>
 38  * </ul>
 39  * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
 40  * </p>
 41  * @name KJUR.crypto
 42  * @namespace
 43  */
 44 if (typeof KJUR.crypto == "undefined" || !KJUR.crypto) KJUR.crypto = {};
 45 
 46 /**
 47  * static object for cryptographic function utilities
 48  * @name KJUR.crypto.Util
 49  * @class static object for cryptographic function utilities
 50  * @property {Array} DIGESTINFOHEAD PKCS#1 DigestInfo heading hexadecimal bytes for each hash algorithms
 51  * @property {Array} DEFAULTPROVIDER associative array of default provider name for each hash and signature algorithms
 52  * @description
 53  */
 54 KJUR.crypto.Util = new function() {
 55     this.DIGESTINFOHEAD = {
 56 	'sha1':      "3021300906052b0e03021a05000414",
 57         'sha224':    "302d300d06096086480165030402040500041c",
 58 	'sha256':    "3031300d060960864801650304020105000420",
 59 	'sha384':    "3041300d060960864801650304020205000430",
 60 	'sha512':    "3051300d060960864801650304020305000440",
 61 	'md2':       "3020300c06082a864886f70d020205000410",
 62 	'md5':       "3020300c06082a864886f70d020505000410",
 63 	'ripemd160': "3021300906052b2403020105000414",
 64     };
 65 
 66     /*
 67      * @since crypto 1.1.1
 68      */
 69     this.DEFAULTPROVIDER = {
 70 	'md5':			'cryptojs',
 71 	'sha1':			'cryptojs',
 72 	'sha224':		'cryptojs',
 73 	'sha256':		'cryptojs',
 74 	'sha384':		'cryptojs',
 75 	'sha512':		'cryptojs',
 76 	'ripemd160':		'cryptojs',
 77 	'hmacmd5':		'cryptojs',
 78 	'hmacsha1':		'cryptojs',
 79 	'hmacsha224':		'cryptojs',
 80 	'hmacsha256':		'cryptojs',
 81 	'hmacsha384':		'cryptojs',
 82 	'hmacsha512':		'cryptojs',
 83 	'hmacripemd160':	'cryptojs',
 84 
 85 	'MD5withRSA':		'cryptojs/jsrsa',
 86 	'SHA1withRSA':		'cryptojs/jsrsa',
 87 	'SHA224withRSA':	'cryptojs/jsrsa',
 88 	'SHA256withRSA':	'cryptojs/jsrsa',
 89 	'SHA384withRSA':	'cryptojs/jsrsa',
 90 	'SHA512withRSA':	'cryptojs/jsrsa',
 91 	'RIPEMD160withRSA':	'cryptojs/jsrsa',
 92 
 93 	'MD5withECDSA':		'cryptojs/jsrsa',
 94 	'SHA1withECDSA':	'cryptojs/jsrsa',
 95 	'SHA224withECDSA':	'cryptojs/jsrsa',
 96 	'SHA256withECDSA':	'cryptojs/jsrsa',
 97 	'SHA384withECDSA':	'cryptojs/jsrsa',
 98 	'SHA512withECDSA':	'cryptojs/jsrsa',
 99 	'RIPEMD160withECDSA':	'cryptojs/jsrsa',
100 
101 	'SHA1withDSA':		'cryptojs/jsrsa',
102 	'SHA224withDSA':	'cryptojs/jsrsa',
103 	'SHA256withDSA':	'cryptojs/jsrsa',
104 
105 	'MD5withRSAandMGF1':		'cryptojs/jsrsa',
106 	'SHAwithRSAandMGF1':		'cryptojs/jsrsa',
107 	'SHA1withRSAandMGF1':		'cryptojs/jsrsa',
108 	'SHA224withRSAandMGF1':		'cryptojs/jsrsa',
109 	'SHA256withRSAandMGF1':		'cryptojs/jsrsa',
110 	'SHA384withRSAandMGF1':		'cryptojs/jsrsa',
111 	'SHA512withRSAandMGF1':		'cryptojs/jsrsa',
112 	'RIPEMD160withRSAandMGF1':	'cryptojs/jsrsa',
113     };
114 
115     /*
116      * @since crypto 1.1.2
117      */
118     this.CRYPTOJSMESSAGEDIGESTNAME = {
119 	'md5':		CryptoJS.algo.MD5,
120 	'sha1':		CryptoJS.algo.SHA1,
121 	'sha224':	CryptoJS.algo.SHA224,
122 	'sha256':	CryptoJS.algo.SHA256,
123 	'sha384':	CryptoJS.algo.SHA384,
124 	'sha512':	CryptoJS.algo.SHA512,
125 	'ripemd160':	CryptoJS.algo.RIPEMD160
126     };
127 
128     /**
129      * get hexadecimal DigestInfo
130      * @name getDigestInfoHex
131      * @memberOf KJUR.crypto.Util
132      * @function
133      * @param {String} hHash hexadecimal hash value
134      * @param {String} alg hash algorithm name (ex. 'sha1')
135      * @return {String} hexadecimal string DigestInfo ASN.1 structure
136      */
137     this.getDigestInfoHex = function(hHash, alg) {
138 	if (typeof this.DIGESTINFOHEAD[alg] == "undefined")
139 	    throw "alg not supported in Util.DIGESTINFOHEAD: " + alg;
140 	return this.DIGESTINFOHEAD[alg] + hHash;
141     };
142 
143     /**
144      * get PKCS#1 padded hexadecimal DigestInfo
145      * @name getPaddedDigestInfoHex
146      * @memberOf KJUR.crypto.Util
147      * @function
148      * @param {String} hHash hexadecimal hash value of message to be signed
149      * @param {String} alg hash algorithm name (ex. 'sha1')
150      * @param {Integer} keySize key bit length (ex. 1024)
151      * @return {String} hexadecimal string of PKCS#1 padded DigestInfo
152      */
153     this.getPaddedDigestInfoHex = function(hHash, alg, keySize) {
154 	var hDigestInfo = this.getDigestInfoHex(hHash, alg);
155 	var pmStrLen = keySize / 4; // minimum PM length
156 
157 	if (hDigestInfo.length + 22 > pmStrLen) // len(0001+ff(*8)+00+hDigestInfo)=22
158 	    throw "key is too short for SigAlg: keylen=" + keySize + "," + alg;
159 
160 	var hHead = "0001";
161 	var hTail = "00" + hDigestInfo;
162 	var hMid = "";
163 	var fLen = pmStrLen - hHead.length - hTail.length;
164 	for (var i = 0; i < fLen; i += 2) {
165 	    hMid += "ff";
166 	}
167 	var hPaddedMessage = hHead + hMid + hTail;
168 	return hPaddedMessage;
169     };
170 
171     /**
172      * get hexadecimal hash of string with specified algorithm
173      * @name hashString
174      * @memberOf KJUR.crypto.Util
175      * @function
176      * @param {String} s raw input string to be hashed
177      * @param {String} alg hash algorithm name
178      * @return {String} hexadecimal string of hash value
179      * @since 1.1.1
180      */
181     this.hashString = function(s, alg) {
182         var md = new KJUR.crypto.MessageDigest({'alg': alg});
183         return md.digestString(s);
184     };
185 
186     /**
187      * get hexadecimal hash of hexadecimal string with specified algorithm
188      * @name hashHex
189      * @memberOf KJUR.crypto.Util
190      * @function
191      * @param {String} sHex input hexadecimal string to be hashed
192      * @param {String} alg hash algorithm name
193      * @return {String} hexadecimal string of hash value
194      * @since 1.1.1
195      */
196     this.hashHex = function(sHex, alg) {
197         var md = new KJUR.crypto.MessageDigest({'alg': alg});
198         return md.digestHex(sHex);
199     };
200 
201     /**
202      * get hexadecimal SHA1 hash of string
203      * @name sha1
204      * @memberOf KJUR.crypto.Util
205      * @function
206      * @param {String} s raw input string to be hashed
207      * @return {String} hexadecimal string of hash value
208      * @since 1.0.3
209      */
210     this.sha1 = function(s) {
211 	return this.hashString(s, 'sha1');
212     };
213 
214     /**
215      * get hexadecimal SHA256 hash of string
216      * @name sha256
217      * @memberOf KJUR.crypto.Util
218      * @function
219      * @param {String} s raw input string to be hashed
220      * @return {String} hexadecimal string of hash value
221      * @since 1.0.3
222      */
223     this.sha256 = function(s) {
224 	return this.hashString(s, 'sha256');
225     };
226 
227     this.sha256Hex = function(s) {
228 	return this.hashHex(s, 'sha256');
229     };
230 
231     /**
232      * get hexadecimal SHA512 hash of string
233      * @name sha512
234      * @memberOf KJUR.crypto.Util
235      * @function
236      * @param {String} s raw input string to be hashed
237      * @return {String} hexadecimal string of hash value
238      * @since 1.0.3
239      */
240     this.sha512 = function(s) {
241 	return this.hashString(s, 'sha512');
242     };
243 
244     this.sha512Hex = function(s) {
245 	return this.hashHex(s, 'sha512');
246     };
247 
248     /**
249      * check if key object (RSA/DSA/ECDSA) or not
250      * @name isKey
251      * @memberOf KJUR.crypto.Util
252      * @function
253      * @param {Object} obj any type argument to be checked
254      * @return {Boolean} true if this is key object otherwise false
255      * @since 1.0.3
256      */
257     this.isKey = function(obj) {
258 	if (obj instanceof RSAKey ||
259 	    obj instanceof KJUR.crypto.DSA ||
260 	    obj instanceof KJUR.crypto.ECDSA) {
261 	    return true;
262 	} else {
263 	    return false;
264 	}
265     };
266 };
267 
268 /**
269  * get hexadecimal MD5 hash of string
270  * @name md5
271  * @memberOf KJUR.crypto.Util
272  * @function
273  * @param {String} s input string to be hashed
274  * @return {String} hexadecimal string of hash value
275  * @since 1.0.3
276  * @example
277  * Util.md5('aaa') → 47bce5c74f589f4867dbd57e9ca9f808
278  */
279 KJUR.crypto.Util.md5 = function(s) {
280     var md = new KJUR.crypto.MessageDigest({'alg':'md5', 'prov':'cryptojs'});
281     return md.digestString(s);
282 };
283 
284 /**
285  * get hexadecimal RIPEMD160 hash of string
286  * @name ripemd160
287  * @memberOf KJUR.crypto.Util
288  * @function
289  * @param {String} s input string to be hashed
290  * @return {String} hexadecimal string of hash value
291  * @since 1.0.3
292  * @example
293  * KJUR.crypto.Util.ripemd160("aaa") → 08889bd7b151aa174c21f33f59147fa65381edea
294  */
295 KJUR.crypto.Util.ripemd160 = function(s) {
296     var md = new KJUR.crypto.MessageDigest({'alg':'ripemd160', 'prov':'cryptojs'});
297     return md.digestString(s);
298 };
299 
300 // @since jsrsasign 7.0.0 crypto 1.1.11
301 KJUR.crypto.Util.SECURERANDOMGEN = new SecureRandom();
302 
303 /**
304  * get hexadecimal string of random value from with specified byte length<br/>
305  * @name getRandomHexOfNbytes
306  * @memberOf KJUR.crypto.Util
307  * @function
308  * @param {Integer} n length of bytes of random
309  * @return {String} hexadecimal string of random
310  * @since jsrsasign 7.0.0 crypto 1.1.11
311  * @example
312  * KJUR.crypto.Util.getRandomHexOfNbytes(3) → "6314af", "000000" or "001fb4"
313  * KJUR.crypto.Util.getRandomHexOfNbytes(128) → "8fbc..." in 1024bits 
314  */
315 KJUR.crypto.Util.getRandomHexOfNbytes = function(n) {
316     var ba = new Array(n);
317     KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(ba);
318     return BAtohex(ba);
319 };
320 
321 /**
322  * get BigInteger object of random value from with specified byte length<br/>
323  * @name getRandomBigIntegerOfNbytes
324  * @memberOf KJUR.crypto.Util
325  * @function
326  * @param {Integer} n length of bytes of random
327  * @return {BigInteger} BigInteger object of specified random value
328  * @since jsrsasign 7.0.0 crypto 1.1.11
329  * @example
330  * KJUR.crypto.Util.getRandomBigIntegerOfNbytes(3) → 6314af of BigInteger
331  * KJUR.crypto.Util.getRandomBigIntegerOfNbytes(128) → 8fbc... of BigInteger
332  */
333 KJUR.crypto.Util.getRandomBigIntegerOfNbytes = function(n) {
334     return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbytes(n), 16);
335 };
336 
337 /**
338  * get hexadecimal string of random value from with specified bit length<br/>
339  * @name getRandomHexOfNbits
340  * @memberOf KJUR.crypto.Util
341  * @function
342  * @param {Integer} n length of bits of random
343  * @return {String} hexadecimal string of random
344  * @since jsrsasign 7.0.0 crypto 1.1.11
345  * @example
346  * KJUR.crypto.Util.getRandomHexOfNbits(24) → "6314af", "000000" or "001fb4"
347  * KJUR.crypto.Util.getRandomHexOfNbits(1024) → "8fbc..." in 1024bits 
348  */
349 KJUR.crypto.Util.getRandomHexOfNbits = function(n) {
350     var n_remainder = n % 8;
351     var n_quotient = (n - n_remainder) / 8;
352     var ba = new Array(n_quotient + 1);
353     KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(ba);
354     ba[0] = (((255 << n_remainder) & 255) ^ 255) & ba[0];
355     return BAtohex(ba);
356 };
357 
358 /**
359  * get BigInteger object of random value from with specified bit length<br/>
360  * @name getRandomBigIntegerOfNbits
361  * @memberOf KJUR.crypto.Util
362  * @function
363  * @param {Integer} n length of bits of random
364  * @return {BigInteger} BigInteger object of specified random value
365  * @since jsrsasign 7.0.0 crypto 1.1.11
366  * @example
367  * KJUR.crypto.Util.getRandomBigIntegerOfNbits(24) → 6314af of BigInteger
368  * KJUR.crypto.Util.getRandomBigIntegerOfNbits(1024) → 8fbc... of BigInteger
369  */
370 KJUR.crypto.Util.getRandomBigIntegerOfNbits = function(n) {
371     return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbits(n), 16);
372 };
373 
374 /**
375  * get BigInteger object of random value from zero to max value<br/>
376  * @name getRandomBigIntegerZeroToMax
377  * @memberOf KJUR.crypto.Util
378  * @function
379  * @param {BigInteger} biMax max value of BigInteger object for random value
380  * @return {BigInteger} BigInteger object of specified random value
381  * @since jsrsasign 7.0.0 crypto 1.1.11
382  * @description
383  * This static method generates a BigInteger object with random value
384  * greater than or equal to zero and smaller than or equal to biMax
385  * (i.e. 0 ≤ result ≤ biMax).
386  * @example
387  * biMax = new BigInteger("3fa411...", 16);
388  * KJUR.crypto.Util.getRandomBigIntegerZeroToMax(biMax) → 8fbc... of BigInteger
389  */
390 KJUR.crypto.Util.getRandomBigIntegerZeroToMax = function(biMax) {
391     var bitLenMax = biMax.bitLength();
392     while (1) {
393 	var biRand = KJUR.crypto.Util.getRandomBigIntegerOfNbits(bitLenMax);
394 	if (biMax.compareTo(biRand) != -1) return biRand;
395     }
396 };
397 
398 /**
399  * get BigInteger object of random value from min value to max value<br/>
400  * @name getRandomBigIntegerMinToMax
401  * @memberOf KJUR.crypto.Util
402  * @function
403  * @param {BigInteger} biMin min value of BigInteger object for random value
404  * @param {BigInteger} biMax max value of BigInteger object for random value
405  * @return {BigInteger} BigInteger object of specified random value
406  * @since jsrsasign 7.0.0 crypto 1.1.11
407  * @description
408  * This static method generates a BigInteger object with random value
409  * greater than or equal to biMin and smaller than or equal to biMax
410  * (i.e. biMin ≤ result ≤ biMax).
411  * @example
412  * biMin = new BigInteger("2fa411...", 16);
413  * biMax = new BigInteger("3fa411...", 16);
414  * KJUR.crypto.Util.getRandomBigIntegerMinToMax(biMin, biMax) → 32f1... of BigInteger
415  */
416 KJUR.crypto.Util.getRandomBigIntegerMinToMax = function(biMin, biMax) {
417     var flagCompare = biMin.compareTo(biMax);
418     if (flagCompare == 1) throw "biMin is greater than biMax";
419     if (flagCompare == 0) return biMin;
420 
421     var biDiff = biMax.subtract(biMin);
422     var biRand = KJUR.crypto.Util.getRandomBigIntegerZeroToMax(biDiff);
423     return biRand.add(biMin);
424 };
425 
426 // === Mac ===============================================================
427 
428 /**
429  * MessageDigest class which is very similar to java.security.MessageDigest class<br/>
430  * @name KJUR.crypto.MessageDigest
431  * @class MessageDigest class which is very similar to java.security.MessageDigest class
432  * @param {Array} params parameters for constructor
433  * @property {Array} HASHLENGTH static Array of resulted byte length of hash (ex. HASHLENGTH["sha1"] == 20)
434  * @description
435  * <br/>
436  * Currently this supports following algorithm and providers combination:
437  * <ul>
438  * <li>md5 - cryptojs</li>
439  * <li>sha1 - cryptojs</li>
440  * <li>sha224 - cryptojs</li>
441  * <li>sha256 - cryptojs</li>
442  * <li>sha384 - cryptojs</li>
443  * <li>sha512 - cryptojs</li>
444  * <li>ripemd160 - cryptojs</li>
445  * <li>sha256 - sjcl (NEW from crypto.js 1.0.4)</li>
446  * </ul>
447  * @example
448  * // CryptoJS provider sample
449  * var md = new KJUR.crypto.MessageDigest({alg: "sha1", prov: "cryptojs"});
450  * md.updateString('aaa')
451  * var mdHex = md.digest()
452  *
453  * // SJCL(Stanford JavaScript Crypto Library) provider sample
454  * var md = new KJUR.crypto.MessageDigest({alg: "sha256", prov: "sjcl"}); // sjcl supports sha256 only
455  * md.updateString('aaa')
456  * var mdHex = md.digest()
457  *
458  * // HASHLENGTH property
459  * KJUR.crypto.MessageDigest.HASHLENGTH['sha1'] &rarr 20
460  * KJUR.crypto.MessageDigest.HASHLENGTH['sha512'] &rarr 64
461  */
462 KJUR.crypto.MessageDigest = function(params) {
463     var md = null;
464     var algName = null;
465     var provName = null;
466 
467     /**
468      * set hash algorithm and provider<br/>
469      * @name setAlgAndProvider
470      * @memberOf KJUR.crypto.MessageDigest#
471      * @function
472      * @param {String} alg hash algorithm name
473      * @param {String} prov provider name
474      * @description
475      * This methods set an algorithm and a cryptographic provider.<br/>
476      * Here is acceptable algorithm names ignoring cases and hyphens:
477      * <ul>
478      * <li>MD5</li>
479      * <li>SHA1</li>
480      * <li>SHA224</li>
481      * <li>SHA256</li>
482      * <li>SHA384</li>
483      * <li>SHA512</li>
484      * <li>RIPEMD160</li>
485      * </ul>
486      * NOTE: Since jsrsasign 6.2.0 crypto 1.1.10, this method ignores
487      * upper or lower cases. Also any hyphens (i.e. "-") will be ignored
488      * so that "SHA1" or "SHA-1" will be acceptable.
489      * @example
490      * // for SHA1
491      * md.setAlgAndProvider('sha1', 'cryptojs');
492      * md.setAlgAndProvider('SHA1');
493      * // for RIPEMD160
494      * md.setAlgAndProvider('ripemd160', 'cryptojs');
495      */
496     this.setAlgAndProvider = function(alg, prov) {
497 	alg = KJUR.crypto.MessageDigest.getCanonicalAlgName(alg);
498 
499 	if (alg !== null && prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];
500 
501 	// for cryptojs
502 	if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(alg) != -1 &&
503 	    prov == 'cryptojs') {
504 	    try {
505 		this.md = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[alg].create();
506 	    } catch (ex) {
507 		throw "setAlgAndProvider hash alg set fail alg=" + alg + "/" + ex;
508 	    }
509 	    this.updateString = function(str) {
510 		this.md.update(str);
511 	    };
512 	    this.updateHex = function(hex) {
513 		var wHex = CryptoJS.enc.Hex.parse(hex);
514 		this.md.update(wHex);
515 	    };
516 	    this.digest = function() {
517 		var hash = this.md.finalize();
518 		return hash.toString(CryptoJS.enc.Hex);
519 	    };
520 	    this.digestString = function(str) {
521 		this.updateString(str);
522 		return this.digest();
523 	    };
524 	    this.digestHex = function(hex) {
525 		this.updateHex(hex);
526 		return this.digest();
527 	    };
528 	}
529 	if (':sha256:'.indexOf(alg) != -1 &&
530 	    prov == 'sjcl') {
531 	    try {
532 		this.md = new sjcl.hash.sha256();
533 	    } catch (ex) {
534 		throw "setAlgAndProvider hash alg set fail alg=" + alg + "/" + ex;
535 	    }
536 	    this.updateString = function(str) {
537 		this.md.update(str);
538 	    };
539 	    this.updateHex = function(hex) {
540 		var baHex = sjcl.codec.hex.toBits(hex);
541 		this.md.update(baHex);
542 	    };
543 	    this.digest = function() {
544 		var hash = this.md.finalize();
545 		return sjcl.codec.hex.fromBits(hash);
546 	    };
547 	    this.digestString = function(str) {
548 		this.updateString(str);
549 		return this.digest();
550 	    };
551 	    this.digestHex = function(hex) {
552 		this.updateHex(hex);
553 		return this.digest();
554 	    };
555 	}
556     };
557 
558     /**
559      * update digest by specified string
560      * @name updateString
561      * @memberOf KJUR.crypto.MessageDigest#
562      * @function
563      * @param {String} str string to update
564      * @description
565      * @example
566      * md.updateString('New York');
567      */
568     this.updateString = function(str) {
569 	throw "updateString(str) not supported for this alg/prov: " + this.algName + "/" + this.provName;
570     };
571 
572     /**
573      * update digest by specified hexadecimal string
574      * @name updateHex
575      * @memberOf KJUR.crypto.MessageDigest#
576      * @function
577      * @param {String} hex hexadecimal string to update
578      * @description
579      * @example
580      * md.updateHex('0afe36');
581      */
582     this.updateHex = function(hex) {
583 	throw "updateHex(hex) not supported for this alg/prov: " + this.algName + "/" + this.provName;
584     };
585 
586     /**
587      * completes hash calculation and returns hash result
588      * @name digest
589      * @memberOf KJUR.crypto.MessageDigest#
590      * @function
591      * @description
592      * @example
593      * md.digest()
594      */
595     this.digest = function() {
596 	throw "digest() not supported for this alg/prov: " + this.algName + "/" + this.provName;
597     };
598 
599     /**
600      * performs final update on the digest using string, then completes the digest computation
601      * @name digestString
602      * @memberOf KJUR.crypto.MessageDigest#
603      * @function
604      * @param {String} str string to final update
605      * @description
606      * @example
607      * md.digestString('aaa')
608      */
609     this.digestString = function(str) {
610 	throw "digestString(str) not supported for this alg/prov: " + this.algName + "/" + this.provName;
611     };
612 
613     /**
614      * performs final update on the digest using hexadecimal string, then completes the digest computation
615      * @name digestHex
616      * @memberOf KJUR.crypto.MessageDigest#
617      * @function
618      * @param {String} hex hexadecimal string to final update
619      * @description
620      * @example
621      * md.digestHex('0f2abd')
622      */
623     this.digestHex = function(hex) {
624 	throw "digestHex(hex) not supported for this alg/prov: " + this.algName + "/" + this.provName;
625     };
626 
627     if (params !== undefined) {
628 	if (params['alg'] !== undefined) {
629 	    this.algName = params['alg'];
630 	    if (params['prov'] === undefined)
631 		this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
632 	    this.setAlgAndProvider(this.algName, this.provName);
633 	}
634     }
635 };
636 
637 /**
638  * get canonical hash algorithm name<br/>
639  * @name getCanonicalAlgName
640  * @memberOf KJUR.crypto.MessageDigest
641  * @function
642  * @param {String} alg hash algorithm name (ex. MD5, SHA-1, SHA1, SHA512 et.al.)
643  * @return {String} canonical hash algorithm name
644  * @since jsrsasign 6.2.0 crypto 1.1.10
645  * @description
646  * This static method normalizes from any hash algorithm name such as
647  * "SHA-1", "SHA1", "MD5", "sha512" to lower case name without hyphens
648  * such as "sha1".
649  * @example
650  * KJUR.crypto.MessageDigest.getCanonicalAlgName("SHA-1") &rarr "sha1"
651  * KJUR.crypto.MessageDigest.getCanonicalAlgName("MD5")   &rarr "md5"
652  */
653 KJUR.crypto.MessageDigest.getCanonicalAlgName = function(alg) {
654     if (typeof alg === "string") {
655 	alg = alg.toLowerCase();
656 	alg = alg.replace(/-/, '');
657     }
658     return alg;
659 };
660 
661 /**
662  * get resulted hash byte length for specified algorithm name<br/>
663  * @name getHashLength
664  * @memberOf KJUR.crypto.MessageDigest
665  * @function
666  * @param {String} alg non-canonicalized hash algorithm name (ex. MD5, SHA-1, SHA1, SHA512 et.al.)
667  * @return {Integer} resulted hash byte length
668  * @since jsrsasign 6.2.0 crypto 1.1.10
669  * @description
670  * This static method returns resulted byte length for specified algorithm name such as "SHA-1".
671  * @example
672  * KJUR.crypto.MessageDigest.getHashLength("SHA-1") &rarr 20
673  * KJUR.crypto.MessageDigest.getHashLength("sha1") &rarr 20
674  */
675 KJUR.crypto.MessageDigest.getHashLength = function(alg) {
676     var MD = KJUR.crypto.MessageDigest
677     var alg2 = MD.getCanonicalAlgName(alg);
678     if (MD.HASHLENGTH[alg2] === undefined)
679 	throw "not supported algorithm: " + alg;
680     return MD.HASHLENGTH[alg2];
681 };
682 
683 // described in KJUR.crypto.MessageDigest class (since jsrsasign 6.2.0 crypto 1.1.10)
684 KJUR.crypto.MessageDigest.HASHLENGTH = {
685     'md5':		16,
686     'sha1':		20,
687     'sha224':		28,
688     'sha256':		32,
689     'sha384':		48,
690     'sha512':		64,
691     'ripemd160':	20
692 };
693 
694 // === Mac ===============================================================
695 
696 /**
697  * Mac(Message Authentication Code) class which is very similar to java.security.Mac class 
698  * @name KJUR.crypto.Mac
699  * @class Mac class which is very similar to java.security.Mac class
700  * @param {Array} params parameters for constructor
701  * @description
702  * <br/>
703  * Currently this supports following algorithm and providers combination:
704  * <ul>
705  * <li>hmacmd5 - cryptojs</li>
706  * <li>hmacsha1 - cryptojs</li>
707  * <li>hmacsha224 - cryptojs</li>
708  * <li>hmacsha256 - cryptojs</li>
709  * <li>hmacsha384 - cryptojs</li>
710  * <li>hmacsha512 - cryptojs</li>
711  * </ul>
712  * NOTE: HmacSHA224 and HmacSHA384 issue was fixed since jsrsasign 4.1.4.
713  * Please use 'ext/cryptojs-312-core-fix*.js' instead of 'core.js' of original CryptoJS
714  * to avoid those issue.
715  * <br/>
716  * NOTE2: Hmac signature bug was fixed in jsrsasign 4.9.0 by providing CryptoJS
717  * bug workaround.
718  * <br/>
719  * Please see {@link KJUR.crypto.Mac.setPassword}, how to provide password
720  * in various ways in detail.
721  * @example
722  * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": "pass"});
723  * mac.updateString('aaa')
724  * mac.doFinal() → "5737da..."
725  *
726  * // other password representation 
727  * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": {"hex":  "6161"}});
728  * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": {"utf8": "aa"}});
729  * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": {"rstr": "\x61\x61"}});
730  * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": {"b64":  "Mi02/+...a=="}});
731  * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": {"b64u": "Mi02_-...a"}});
732  */
733 KJUR.crypto.Mac = function(params) {
734     var mac = null;
735     var pass = null;
736     var algName = null;
737     var provName = null;
738     var algProv = null;
739 
740     this.setAlgAndProvider = function(alg, prov) {
741 	alg = alg.toLowerCase();
742 
743 	if (alg == null) alg = "hmacsha1";
744 
745 	alg = alg.toLowerCase();
746         if (alg.substr(0, 4) != "hmac") {
747 	    throw "setAlgAndProvider unsupported HMAC alg: " + alg;
748 	}
749 
750 	if (prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];
751 	this.algProv = alg + "/" + prov;
752 
753 	var hashAlg = alg.substr(4);
754 
755 	// for cryptojs
756 	if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(hashAlg) != -1 &&
757 	    prov == 'cryptojs') {
758 	    try {
759 		var mdObj = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[hashAlg];
760 		this.mac = CryptoJS.algo.HMAC.create(mdObj, this.pass);
761 	    } catch (ex) {
762 		throw "setAlgAndProvider hash alg set fail hashAlg=" + hashAlg + "/" + ex;
763 	    }
764 	    this.updateString = function(str) {
765 		this.mac.update(str);
766 	    };
767 	    this.updateHex = function(hex) {
768 		var wHex = CryptoJS.enc.Hex.parse(hex);
769 		this.mac.update(wHex);
770 	    };
771 	    this.doFinal = function() {
772 		var hash = this.mac.finalize();
773 		return hash.toString(CryptoJS.enc.Hex);
774 	    };
775 	    this.doFinalString = function(str) {
776 		this.updateString(str);
777 		return this.doFinal();
778 	    };
779 	    this.doFinalHex = function(hex) {
780 		this.updateHex(hex);
781 		return this.doFinal();
782 	    };
783 	}
784     };
785 
786     /**
787      * update digest by specified string<br/>
788      * @name updateString
789      * @memberOf KJUR.crypto.Mac#
790      * @function
791      * @param {String} str string to update
792      *
793      * @description
794      * @example
795      * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": "pass"});
796      * mac.updateString('aaa')
797      * mac.doFinal() → "5737da..."
798      */
799     this.updateString = function(str) {
800 	throw "updateString(str) not supported for this alg/prov: " + this.algProv;
801     };
802 
803     /**
804      * update digest by specified hexadecimal string<br/>
805      * @name updateHex
806      * @memberOf KJUR.crypto.Mac#
807      * @function
808      * @param {String} hex hexadecimal string to update
809      *
810      * @description
811      * @example
812      * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": "pass"});
813      * mac.updateHex('616161')
814      * mac.doFinal() → "5737da..."
815      */
816     this.updateHex = function(hex) {
817 	throw "updateHex(hex) not supported for this alg/prov: " + this.algProv;
818     };
819 
820     /**
821      * completes hash calculation and returns hash result<br/>
822      * @name doFinal
823      * @memberOf KJUR.crypto.Mac#
824      * @function
825      * @returns hexadecimal string of Mac result value
826      *
827      * @description
828      * @example
829      * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": "pass"});
830      * mac.updateString('aaa')
831      * mac.doFinal() → "5737da..."
832      */
833     this.doFinal = function() {
834 	throw "digest() not supported for this alg/prov: " + this.algProv;
835     };
836 
837     /**
838      * performs final update on the digest using string, then completes the digest computation<br/>
839      * @name doFinalString
840      * @memberOf KJUR.crypto.Mac#
841      * @function
842      * @param {String} str raw string to final update
843      * @returns hexadecimal string of Mac result value
844      *
845      * @description
846      * @example
847      * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": "pass"});
848      * mac.doFinalString("aaa") → "5737da..."
849      */
850     this.doFinalString = function(str) {
851 	throw "digestString(str) not supported for this alg/prov: " + this.algProv;
852     };
853 
854     /**
855      * performs final update on the digest using hexadecimal string, then completes the digest computation<br/>
856      * @name doFinalHex
857      * @memberOf KJUR.crypto.Mac#
858      * @function
859      * @param {String} hex hexadecimal string to final update
860      * @returns hexadecimal string of Mac result value
861      *
862      * @description
863      * @example
864      * var mac = new KJUR.crypto.Mac({alg: "HmacSHA256", "pass": "pass"});
865      * mac.doFinalHex("616161") → "5737da..."
866      */
867     this.doFinalHex = function(hex) {
868 	throw "digestHex(hex) not supported for this alg/prov: " + this.algProv;
869     };
870 
871     /**
872      * set password for Mac<br/>
873      * @name setPassword
874      * @memberOf KJUR.crypto.Mac#
875      * @function
876      * @param {Object} pass password for Mac
877      * @since crypto 1.1.7 jsrsasign 4.9.0
878      * @description
879      * This method will set password for (H)Mac internally.
880      * Argument 'pass' can be specified as following:
881      * <ul>
882      * <li>even length string of 0..9, a..f or A-F: implicitly specified as hexadecimal string</li>
883      * <li>not above string: implicitly specified as raw string</li>
884      * <li>{rstr: "\x65\x70"}: explicitly specified as raw string</li>
885      * <li>{hex: "6570"}: explicitly specified as hexacedimal string</li>
886      * <li>{utf8: "秘密"}: explicitly specified as UTF8 string</li>
887      * <li>{b64: "Mi78..=="}: explicitly specified as Base64 string</li>
888      * <li>{b64u: "Mi7-_"}: explicitly specified as Base64URL string</li>
889      * </ul>
890      * It is *STRONGLY RECOMMENDED* that explicit representation of password argument
891      * to avoid ambiguity. For example string  "6161" can mean a string "6161" or 
892      * a hexadecimal string of "aa" (i.e. \x61\x61).
893      * @example
894      * mac = KJUR.crypto.Mac({'alg': 'hmacsha256'});
895      * // set password by implicit raw string
896      * mac.setPassword("\x65\x70\xb9\x0b");
897      * mac.setPassword("password");
898      * // set password by implicit hexadecimal string
899      * mac.setPassword("6570b90b");
900      * mac.setPassword("6570B90B");
901      * // set password by explicit raw string
902      * mac.setPassword({"rstr": "\x65\x70\xb9\x0b"});
903      * // set password by explicit hexadecimal string
904      * mac.setPassword({"hex": "6570b90b"});
905      * // set password by explicit utf8 string
906      * mac.setPassword({"utf8": "passwordパスワード");
907      * // set password by explicit Base64 string
908      * mac.setPassword({"b64": "Mb+c3f/=="});
909      * // set password by explicit Base64URL string
910      * mac.setPassword({"b64u": "Mb-c3f_"});
911      */
912     this.setPassword = function(pass) {
913 	// internal this.pass shall be CryptoJS DWord Object for CryptoJS bug
914 	// work around. CrytoJS HMac password can be passed by
915 	// raw string as described in the manual however it doesn't
916 	// work properly in some case. If password was passed
917 	// by CryptoJS DWord which is not described in the manual
918 	// it seems to work. (fixed since crypto 1.1.7)
919 
920 	if (typeof pass == 'string') {
921 	    var hPass = pass;
922 	    if (pass.length % 2 == 1 || ! pass.match(/^[0-9A-Fa-f]+$/)) { // raw str
923 		hPass = rstrtohex(pass);
924 	    }
925 	    this.pass = CryptoJS.enc.Hex.parse(hPass);
926 	    return;
927 	}
928 
929 	if (typeof pass != 'object')
930 	    throw "KJUR.crypto.Mac unsupported password type: " + pass;
931 	
932 	var hPass = null;
933 	if (pass.hex  !== undefined) {
934 	    if (pass.hex.length % 2 != 0 || ! pass.hex.match(/^[0-9A-Fa-f]+$/))
935 		throw "Mac: wrong hex password: " + pass.hex;
936 	    hPass = pass.hex;
937 	}
938 	if (pass.utf8 !== undefined) hPass = utf8tohex(pass.utf8);
939 	if (pass.rstr !== undefined) hPass = rstrtohex(pass.rstr);
940 	if (pass.b64  !== undefined) hPass = b64tohex(pass.b64);
941 	if (pass.b64u !== undefined) hPass = b64utohex(pass.b64u);
942 
943 	if (hPass == null)
944 	    throw "KJUR.crypto.Mac unsupported password type: " + pass;
945 
946 	this.pass = CryptoJS.enc.Hex.parse(hPass);
947     };
948 
949     if (params !== undefined) {
950 	if (params.pass !== undefined) {
951 	    this.setPassword(params.pass);
952 	}
953 	if (params.alg !== undefined) {
954 	    this.algName = params.alg;
955 	    if (params['prov'] === undefined)
956 		this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
957 	    this.setAlgAndProvider(this.algName, this.provName);
958 	}
959     }
960 };
961 
962 // ====== Signature class ====================================================
963 /**
964  * Signature class which is very similar to java.security.Signature class
965  * @name KJUR.crypto.Signature
966  * @class Signature class which is very similar to java.security.Signature class
967  * @param {Array} params parameters for constructor
968  * @property {String} state Current state of this signature object whether 'SIGN', 'VERIFY' or null
969  * @description
970  * <br/>
971  * As for params of constructor's argument, it can be specify following attributes:
972  * <ul>
973  * <li>alg - signature algorithm name (ex. {MD5,SHA1,SHA224,SHA256,SHA384,SHA512,RIPEMD160}with{RSA,ECDSA,DSA})</li>
974  * <li>provider - currently 'cryptojs/jsrsa' only</li>
975  * </ul>
976  * <h4>SUPPORTED ALGORITHMS AND PROVIDERS</h4>
977  * This Signature class supports following signature algorithm and provider names:
978  * <ul>
979  * <li>MD5withRSA - cryptojs/jsrsa</li>
980  * <li>SHA1withRSA - cryptojs/jsrsa</li>
981  * <li>SHA224withRSA - cryptojs/jsrsa</li>
982  * <li>SHA256withRSA - cryptojs/jsrsa</li>
983  * <li>SHA384withRSA - cryptojs/jsrsa</li>
984  * <li>SHA512withRSA - cryptojs/jsrsa</li>
985  * <li>RIPEMD160withRSA - cryptojs/jsrsa</li>
986  * <li>MD5withECDSA - cryptojs/jsrsa</li>
987  * <li>SHA1withECDSA - cryptojs/jsrsa</li>
988  * <li>SHA224withECDSA - cryptojs/jsrsa</li>
989  * <li>SHA256withECDSA - cryptojs/jsrsa</li>
990  * <li>SHA384withECDSA - cryptojs/jsrsa</li>
991  * <li>SHA512withECDSA - cryptojs/jsrsa</li>
992  * <li>RIPEMD160withECDSA - cryptojs/jsrsa</li>
993  * <li>MD5withRSAandMGF1 - cryptojs/jsrsa</li>
994  * <li>SHAwithRSAandMGF1 - cryptojs/jsrsa</li>
995  * <li>SHA1withRSAandMGF1 - cryptojs/jsrsa</li>
996  * <li>SHA224withRSAandMGF1 - cryptojs/jsrsa</li>
997  * <li>SHA256withRSAandMGF1 - cryptojs/jsrsa</li>
998  * <li>SHA384withRSAandMGF1 - cryptojs/jsrsa</li>
999  * <li>SHA512withRSAandMGF1 - cryptojs/jsrsa</li>
1000  * <li>RIPEMD160withRSAandMGF1 - cryptojs/jsrsa</li>
1001  * <li>SHA1withDSA - cryptojs/jsrsa</li>
1002  * <li>SHA224withDSA - cryptojs/jsrsa</li>
1003  * <li>SHA256withDSA - cryptojs/jsrsa</li>
1004  * </ul>
1005  * As for RSA-PSS signature algorithm names and signing parameters 
1006  * such as MGF function and salt length, please see
1007  * {@link KJUR.asn1.x509.AlgorithmIdentifier} class.
1008  *
1009  * Here are supported elliptic cryptographic curve names and their aliases for ECDSA:
1010  * <ul>
1011  * <li>secp256k1</li>
1012  * <li>secp256r1, NIST P-256, P-256, prime256v1</li>
1013  * <li>secp384r1, NIST P-384, P-384</li>
1014  * <li>secp521r1, NIST P-521, P-521</li>
1015  * </ul>
1016  * NOTE1: DSA signing algorithm is also supported since crypto 1.1.5.
1017  * <h4>EXAMPLES</h4>
1018  * @example
1019  * // RSA signature generation
1020  * var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"});
1021  * sig.init(prvKeyPEM);
1022  * sig.updateString('aaa');
1023  * var hSigVal = sig.sign();
1024  *
1025  * // DSA signature validation
1026  * var sig2 = new KJUR.crypto.Signature({"alg": "SHA1withDSA"});
1027  * sig2.init(certPEM);
1028  * sig.updateString('aaa');
1029  * var isValid = sig2.verify(hSigVal);
1030  * 
1031  * // ECDSA signing
1032  * var sig = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});
1033  * sig.init(prvKeyPEM);
1034  * sig.updateString('aaa');
1035  * var sigValueHex = sig.sign();
1036  *
1037  * // ECDSA verifying
1038  * var sig2 = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});
1039  * sig.init(certPEM);
1040  * sig.updateString('aaa');
1041  * var isValid = sig.verify(sigValueHex);
1042  */
1043 KJUR.crypto.Signature = function(params) {
1044     var prvKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for signing
1045     var pubKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for verifying
1046 
1047     var md = null; // KJUR.crypto.MessageDigest object
1048     var sig = null;
1049     var algName = null;
1050     var provName = null;
1051     var algProvName = null;
1052     var mdAlgName = null;
1053     var pubkeyAlgName = null;	// rsa,ecdsa,rsaandmgf1(=rsapss)
1054     var state = null;
1055     var pssSaltLen = -1;
1056     var initParams = null;
1057 
1058     var sHashHex = null; // hex hash value for hex
1059     var hDigestInfo = null;
1060     var hPaddedDigestInfo = null;
1061     var hSign = null;
1062 
1063     this._setAlgNames = function() {
1064     var matchResult = this.algName.match(/^(.+)with(.+)$/);
1065 	if (matchResult) {
1066 	    this.mdAlgName = matchResult[1].toLowerCase();
1067 	    this.pubkeyAlgName = matchResult[2].toLowerCase();
1068 	    if (this.pubkeyAlgName == "rsaandmgf1" &&
1069 	        this.mdAlgName == "sha") {
1070 		this.mdAlgName = "sha1";
1071 	    }
1072 	}
1073     };
1074 
1075     this._zeroPaddingOfSignature = function(hex, bitLength) {
1076 	var s = "";
1077 	var nZero = bitLength / 4 - hex.length;
1078 	for (var i = 0; i < nZero; i++) {
1079 	    s = s + "0";
1080 	}
1081 	return s + hex;
1082     };
1083 
1084     /**
1085      * set signature algorithm and provider
1086      * @name setAlgAndProvider
1087      * @memberOf KJUR.crypto.Signature#
1088      * @function
1089      * @param {String} alg signature algorithm name
1090      * @param {String} prov provider name
1091      * @description
1092      * @example
1093      * md.setAlgAndProvider('SHA1withRSA', 'cryptojs/jsrsa');
1094      */
1095     this.setAlgAndProvider = function(alg, prov) {
1096 	this._setAlgNames();
1097 	if (prov != 'cryptojs/jsrsa')
1098 	    throw new Error("provider not supported: " + prov);
1099 
1100 	if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(this.mdAlgName) != -1) {
1101 	    try {
1102 		this.md = new KJUR.crypto.MessageDigest({'alg':this.mdAlgName});
1103 	    } catch (ex) {
1104 		throw new Error("setAlgAndProvider hash alg set fail alg=" +
1105 				this.mdAlgName + "/" + ex);
1106 	    }
1107 	    
1108 	    this.init = function(keyparam, pass) {
1109 		var keyObj = null;
1110 		try {
1111 		    if (pass === undefined) {
1112 			keyObj = KEYUTIL.getKey(keyparam);
1113 		    } else {
1114 			keyObj = KEYUTIL.getKey(keyparam, pass);
1115 		    }
1116 		} catch (ex) {
1117 		    throw "init failed:" + ex;
1118 		}
1119 
1120 		if (keyObj.isPrivate === true) {
1121 		    this.prvKey = keyObj;
1122 		    this.state = "SIGN";
1123 		} else if (keyObj.isPublic === true) {
1124 		    this.pubKey = keyObj;
1125 		    this.state = "VERIFY";
1126 		} else {
1127 		    throw "init failed.:" + keyObj;
1128 		}
1129 	    };
1130 
1131 	    this.updateString = function(str) {
1132 		this.md.updateString(str);
1133 	    };
1134 
1135 	    this.updateHex = function(hex) {
1136 		this.md.updateHex(hex);
1137 	    };
1138 
1139 	    this.sign = function() {
1140 		this.sHashHex = this.md.digest();
1141 		// hex parameter EC public key
1142 		if (this.prvKey === undefined &&
1143 		    this.ecprvhex !== undefined &&
1144 		    this.eccurvename !== undefined &&
1145 		    KJUR.crypto.ECDSA !== undefined) {
1146 		    this.prvKey = new KJUR.crypto.ECDSA({'curve': this.eccurvename,
1147 							 prv: this.ecprvhex});
1148 		}
1149 
1150 		// RSAPSS
1151 		if (this.prvKey instanceof RSAKey &&
1152 		    this.pubkeyAlgName === "rsaandmgf1") {
1153 		    this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex,
1154 								    this.mdAlgName,
1155 								    this.pssSaltLen);
1156 		// RSA
1157 		} else if (this.prvKey instanceof RSAKey &&
1158 			   this.pubkeyAlgName === "rsa") {
1159 		    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex,
1160 								 this.mdAlgName);
1161 		// ECDSA
1162 		} else if (this.prvKey instanceof KJUR.crypto.ECDSA) {
1163 		    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);
1164 		// DSA
1165 		} else if (this.prvKey instanceof KJUR.crypto.DSA) {
1166 		    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);
1167 		} else {
1168 		    throw "Signature: unsupported private key alg: " + this.pubkeyAlgName;
1169 		}
1170 		return this.hSign;
1171 	    };
1172 	    this.signString = function(str) {
1173 		this.updateString(str);
1174 		return this.sign();
1175 	    };
1176 	    this.signHex = function(hex) {
1177 		this.updateHex(hex);
1178 		return this.sign();
1179 	    };
1180 	    this.verify = function(hSigVal) {
1181 	        this.sHashHex = this.md.digest();
1182 		// hex parameter EC public key
1183 		if (this.pubKey === undefined &&
1184 		    this.ecpubhex !== undefined &&
1185 		    this.eccurvename !== undefined &&
1186 		    KJUR.crypto.ECDSA !== undefined) {
1187 		    this.pubKey = new KJUR.crypto.ECDSA({curve: this.eccurvename,
1188 							 pub: this.ecpubhex});
1189 		}
1190 
1191 		// RSAPSS
1192 		if (this.pubKey instanceof RSAKey &&
1193 		    this.pubkeyAlgName === "rsaandmgf1") {
1194 		    return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, hSigVal, 
1195 								this.mdAlgName,
1196 								this.pssSaltLen);
1197 		// RSA
1198 		} else if (this.pubKey instanceof RSAKey &&
1199 			   this.pubkeyAlgName === "rsa") {
1200 		    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
1201                 // ECDSA
1202 		} else if (KJUR.crypto.ECDSA !== undefined &&
1203 			   this.pubKey instanceof KJUR.crypto.ECDSA) {
1204 		    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
1205                 // DSA
1206 		} else if (KJUR.crypto.DSA !== undefined &&
1207 			   this.pubKey instanceof KJUR.crypto.DSA) {
1208 		    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
1209 		} else {
1210 		    throw "Signature: unsupported public key alg: " + this.pubkeyAlgName;
1211 		}
1212 	    };
1213 	}
1214     };
1215 
1216     /**
1217      * Initialize this object for signing or verifying depends on key
1218      * @name init
1219      * @memberOf KJUR.crypto.Signature#
1220      * @function
1221      * @param {Object} key specifying public or private key as plain/encrypted PKCS#5/8 PEM file, certificate PEM or {@link RSAKey}, {@link KJUR.crypto.DSA} or {@link KJUR.crypto.ECDSA} object
1222      * @param {String} pass (OPTION) passcode for encrypted private key
1223      * @since crypto 1.1.3
1224      * @description
1225      * This method is very useful initialize method for Signature class since
1226      * you just specify key then this method will automatically initialize it
1227      * using {@link KEYUTIL.getKey} method.
1228      * As for 'key',  following argument type are supported:
1229      * <h5>signing</h5>
1230      * <ul>
1231      * <li>PEM formatted PKCS#8 encrypted RSA/ECDSA private key concluding "BEGIN ENCRYPTED PRIVATE KEY"</li>
1232      * <li>PEM formatted PKCS#5 encrypted RSA/DSA private key concluding "BEGIN RSA/DSA PRIVATE KEY" and ",ENCRYPTED"</li>
1233      * <li>PEM formatted PKCS#8 plain RSA/ECDSA private key concluding "BEGIN PRIVATE KEY"</li>
1234      * <li>PEM formatted PKCS#5 plain RSA/DSA private key concluding "BEGIN RSA/DSA PRIVATE KEY" without ",ENCRYPTED"</li>
1235      * <li>RSAKey object of private key</li>
1236      * <li>KJUR.crypto.ECDSA object of private key</li>
1237      * <li>KJUR.crypto.DSA object of private key</li>
1238      * </ul>
1239      * <h5>verification</h5>
1240      * <ul>
1241      * <li>PEM formatted PKCS#8 RSA/EC/DSA public key concluding "BEGIN PUBLIC KEY"</li>
1242      * <li>PEM formatted X.509 certificate with RSA/EC/DSA public key concluding
1243      *     "BEGIN CERTIFICATE", "BEGIN X509 CERTIFICATE" or "BEGIN TRUSTED CERTIFICATE".</li>
1244      * <li>RSAKey object of public key</li>
1245      * <li>KJUR.crypto.ECDSA object of public key</li>
1246      * <li>KJUR.crypto.DSA object of public key</li>
1247      * </ul>
1248      * @example
1249      * sig.init(sCertPEM)
1250      */
1251     this.init = function(key, pass) {
1252 	throw "init(key, pass) not supported for this alg:prov=" +
1253 	      this.algProvName;
1254     };
1255 
1256     /**
1257      * Updates the data to be signed or verified by a string
1258      * @name updateString
1259      * @memberOf KJUR.crypto.Signature#
1260      * @function
1261      * @param {String} str string to use for the update
1262      * @description
1263      * @example
1264      * sig.updateString('aaa')
1265      */
1266     this.updateString = function(str) {
1267 	throw "updateString(str) not supported for this alg:prov=" + this.algProvName;
1268     };
1269 
1270     /**
1271      * Updates the data to be signed or verified by a hexadecimal string
1272      * @name updateHex
1273      * @memberOf KJUR.crypto.Signature#
1274      * @function
1275      * @param {String} hex hexadecimal string to use for the update
1276      * @description
1277      * @example
1278      * sig.updateHex('1f2f3f')
1279      */
1280     this.updateHex = function(hex) {
1281 	throw "updateHex(hex) not supported for this alg:prov=" + this.algProvName;
1282     };
1283 
1284     /**
1285      * Returns the signature bytes of all data updates as a hexadecimal string
1286      * @name sign
1287      * @memberOf KJUR.crypto.Signature#
1288      * @function
1289      * @return the signature bytes as a hexadecimal string
1290      * @description
1291      * @example
1292      * var hSigValue = sig.sign()
1293      */
1294     this.sign = function() {
1295 	throw "sign() not supported for this alg:prov=" + this.algProvName;
1296     };
1297 
1298     /**
1299      * performs final update on the sign using string, then returns the signature bytes of all data updates as a hexadecimal string
1300      * @name signString
1301      * @memberOf KJUR.crypto.Signature#
1302      * @function
1303      * @param {String} str string to final update
1304      * @return the signature bytes of a hexadecimal string
1305      * @description
1306      * @example
1307      * var hSigValue = sig.signString('aaa')
1308      */
1309     this.signString = function(str) {
1310 	throw "digestString(str) not supported for this alg:prov=" + this.algProvName;
1311     };
1312 
1313     /**
1314      * performs final update on the sign using hexadecimal string, then returns the signature bytes of all data updates as a hexadecimal string
1315      * @name signHex
1316      * @memberOf KJUR.crypto.Signature#
1317      * @function
1318      * @param {String} hex hexadecimal string to final update
1319      * @return the signature bytes of a hexadecimal string
1320      * @description
1321      * @example
1322      * var hSigValue = sig.signHex('1fdc33')
1323      */
1324     this.signHex = function(hex) {
1325 	throw "digestHex(hex) not supported for this alg:prov=" + this.algProvName;
1326     };
1327 
1328     /**
1329      * verifies the passed-in signature.
1330      * @name verify
1331      * @memberOf KJUR.crypto.Signature#
1332      * @function
1333      * @param {String} str string to final update
1334      * @return {Boolean} true if the signature was verified, otherwise false
1335      * @description
1336      * @example
1337      * var isValid = sig.verify('1fbcefdca4823a7(snip)')
1338      */
1339     this.verify = function(hSigVal) {
1340 	throw "verify(hSigVal) not supported for this alg:prov=" + this.algProvName;
1341     };
1342 
1343     this.initParams = params;
1344 
1345     if (params !== undefined) {
1346 	if (params.alg !== undefined) {
1347 	    this.algName = params.alg;
1348 	    if (params.prov === undefined) {
1349 		this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
1350 	    } else {
1351 		this.provName = params.prov;
1352 	    }
1353 	    this.algProvName = this.algName + ":" + this.provName;
1354 	    this.setAlgAndProvider(this.algName, this.provName);
1355 	    this._setAlgNames();
1356 	}
1357 
1358 	if (params['psssaltlen'] !== undefined) this.pssSaltLen = params['psssaltlen'];
1359 
1360 	if (params.prvkeypem !== undefined) {
1361 	    if (params.prvkeypas !== undefined) {
1362 		throw "both prvkeypem and prvkeypas parameters not supported";
1363 	    } else {
1364 		try {
1365 		    var prvKey = KEYUTIL.getKey(params.prvkeypem);
1366 		    this.init(prvKey);
1367 		} catch (ex) {
1368 		    throw "fatal error to load pem private key: " + ex;
1369 		}
1370 	    }
1371 	}
1372     }
1373 };
1374 
1375 // ====== Cipher class ============================================================
1376 /**
1377  * Cipher class to encrypt and decrypt data<br/>
1378  * @name KJUR.crypto.Cipher
1379  * @class Cipher class to encrypt and decrypt data<br/>
1380  * @param {Array} params parameters for constructor
1381  * @since jsrsasign 6.2.0 crypto 1.1.10
1382  * @description
1383  * Here is supported canonicalized cipher algorithm names and its standard names:
1384  * <ul>
1385  * <li>aes256-CBC</li>
1386  * <li>aes128-CBC</li>
1387  * <li>des-EDE3-CBC</li>
1388  * </ul>
1389  * NOTE: From jsrsasign 11.0.0, RSA and RSAOAEP encryption/decryption support is removed
1390  * because of Marvin attack vulnerability.
1391  */
1392 KJUR.crypto.Cipher = function(params) {
1393 };
1394 
1395 /**
1396  * encrypt raw string by specified key and algorithm<br/>
1397  * @name encrypt
1398  * @memberOf KJUR.crypto.Cipher
1399  * @function
1400  * @param {string} s input string to encrypt
1401  * @param {string} hexadecimal string of symmetric cipher key
1402  * @param {string} algName short/long algorithm name for encryption/decryption (OPTION)
1403  * @param {object} param parameters for synchronous cipher such as initial vector (OPTION)
1404  * @return {string} hexadecimal encrypted string
1405  * @since jsrsasign 6.2.0 crypto 1.1.10
1406  *
1407  * @description
1408  * This static method encrypts raw string with specified key and algorithm.
1409  * <br/>
1410  * NOTE: From jsrsasign 10.9.0, asymmetric cipher ({des-EDE3,aes{128,256}}-CBC) is also supported.
1411  * NOTE2: From jsrsasign 11.0.0, RSA and RSAOAEP encryption/decryption support is removed
1412  * because of Marvin attack vulnerability.
1413  *
1414  * @example 
1415  * KJUR.crypto.Cipher.encrypt("12abcd...", "5a7d...", "aes256-CBC", { iv: "1b3c..." }) 
1416  * KJUR.crypto.Cipher.encrypt("12abcd...", "5a7d...", any, { encalg: "aes128-CBC", iv: "1b3c..." }) 
1417  * KJUR.crypto.Cipher.encrypt("12abcd...", any, any, { encalg: "des-EDE3-CBC", iv: "1b3c...", key: "3d41..." }) 
1418  * KJUR.crypto.Cipher.encrypt(any, any, any, { encalg: "des-EDE3-CBC", iv: "1b3c...", key: "3d41...", enc: "12abcd..." }) 
1419  */
1420 KJUR.crypto.Cipher.encrypt = function(s, keyObj, algName, param) {
1421     if (aryval(param, "enclag") != undefined) algName = param.encalg;
1422 
1423     if (typeof algName == "string" && algName.substr(-4) == "-CBC") {
1424 	var hKey = keyObj;
1425 	var hPlain = s;
1426 	if (aryval(param, "key") != undefined) hKey = param.key;
1427 	if (aryval(param, "enc") != undefined) hEnc = param.enc;
1428 	var wKey = CryptoJS.enc.Hex.parse(hKey);
1429 	var wPlain = CryptoJS.enc.Hex.parse(hPlain);
1430 	var wIV = CryptoJS.enc.Hex.parse(param.iv);
1431 	var wEnc;
1432 	if (algName == "des-EDE3-CBC") {
1433 	    wEnc = CryptoJS.TripleDES.encrypt(wPlain, wKey, { iv: wIV });
1434 	} else if (algName == "aes128-CBC" || algName == "aes256-CBC") {
1435 	    wEnc = CryptoJS.AES.encrypt(wPlain, wKey, { iv: wIV });
1436 	} else {
1437 	    throw new Error("unsupported algorithm: " + algName);
1438 	}
1439 	return wEnc + "";
1440     } else {
1441 	throw new Error("Cipher.encrypt: unsupported key or algorithm");
1442     }
1443 };
1444 
1445 /**
1446  * decrypt encrypted hexadecimal string with specified key and algorithm<br/>
1447  * @name decrypt
1448  * @memberOf KJUR.crypto.Cipher
1449  * @function
1450  * @param {string} hex hexadecimal string of encrypted message
1451  * @param {object} hexadecimal string of symmetric cipher key
1452  * @param {string} algName short/long algorithm name for encryption/decryption (OPTION)
1453  * @param {object} param parameters for synchronous cipher such as initial vector (OPTION)
1454  * @return {string} decrypted raw string
1455  * @since jsrsasign 6.2.0 crypto 1.1.10
1456  *
1457  * @description
1458  * This static method decrypts encrypted hexadecimal string with specified key and algorithm.
1459  * <br/>
1460  * NOTE: From jsrsasign 10.9.0, asymmetric cipher ({des-EDE3,aes{128,256}}-CBCis also supported.
1461  * NOTE2: From jsrsasign 11.0.0, RSA and RSAOAEP encryption/decryption support is removed
1462  * because of Marvin attack vulnerability.
1463  *
1464  * @example 
1465  * KJUR.crypto.Cipher.decrypt("12abcd...", "5a7d...", "aes256-CBC", { iv: "1b3c..." }) 
1466  * KJUR.crypto.Cipher.decrypt("12abcd...", "5a7d...", any, { encalg: "aes128-CBC", iv: "1b3c..." }) 
1467  * KJUR.crypto.Cipher.decrypt("12abcd...", any, any, { encalg: "des-EDE3-CBC", iv: "1b3c...", key: "3d41..." }) 
1468  * KJUR.crypto.Cipher.decrypt(any, any, any, { encalg: "des-EDE3-CBC", iv: "1b3c...", key: "3d41...", enc: "12abcd..." }) 
1469  */
1470 KJUR.crypto.Cipher.decrypt = function(hex, keyObj, algName, param) {
1471     if (aryval(param, "enclag") != undefined) algName = param.encalg;
1472 
1473     if (typeof algName == "string" && algName.substr(-4) == "-CBC") {
1474 	var hKey = keyObj;
1475 	var hEnc = hex;
1476 	if (aryval(param, "key") != undefined) hKey = param.key;
1477 	if (aryval(param, "enc") != undefined) hEnc = param.enc;
1478 	var wKey = CryptoJS.enc.Hex.parse(hKey);
1479 	var wEnc = CryptoJS.enc.Hex.parse(hEnc);
1480 	var wIV = CryptoJS.enc.Hex.parse(param.iv);
1481 	var wDec;
1482 	if (algName == "des-EDE3-CBC") {
1483 	    wDec = CryptoJS.TripleDES.decrypt({ ciphertext: wEnc }, wKey, { iv: wIV });
1484 	} else if (algName == "aes128-CBC" || algName == "aes256-CBC") {
1485 	    wDec = CryptoJS.AES.decrypt({ ciphertext: wEnc }, wKey, { iv: wIV });
1486 	} else {
1487 	    throw new Error("unsupported algorithm: " + algName);
1488 	}
1489 	return CryptoJS.enc.Hex.stringify(wDec);
1490     } else {
1491 	throw new Error("Cipher.decrypt: unsupported key or algorithm");
1492     }
1493 };
1494 
1495 /*
1496  * get canonicalized encrypt/decrypt algorithm name by key and short/long algorithm name<br/>
1497  * @name getAlgByKeyAndName
1498  * @memberOf KJUR.crypto.Cipher
1499  * @function
1500  * @param {Object} keyObj RSAKey object or hexadecimal string of symmetric cipher key
1501  * @param {String} algName short/long algorithm name for encryption/decryption
1502  * @return {String} canonicalized algorithm name for encryption/decryption
1503  * @since jsrsasign 6.2.0 crypto 1.1.10
1504  * @description
1505  * Here is supported canonicalized cipher algorithm names and its standard names:
1506  * <ul>
1507  * <li>RSA - RSA/ECB/PKCS1Padding (default for RSAKey)</li>
1508  * <li>RSAOAEP - RSA/ECB/OAEPWithSHA-1AndMGF1Padding</li>
1509  * <li>RSAOAEP224 - RSA/ECB/OAEPWithSHA-224AndMGF1Padding(*)</li>
1510  * <li>RSAOAEP256 - RSA/ECB/OAEPWithSHA-256AndMGF1Padding</li>
1511  * <li>RSAOAEP384 - RSA/ECB/OAEPWithSHA-384AndMGF1Padding(*)</li>
1512  * <li>RSAOAEP512 - RSA/ECB/OAEPWithSHA-512AndMGF1Padding(*)</li>
1513  * </ul>
1514  * NOTE: (*) is not supported in Java JCE.
1515  * @example 
1516  * KJUR.crypto.Cipher.getAlgByKeyAndName(objRSAKey) → "RSA"
1517  * KJUR.crypto.Cipher.getAlgByKeyAndName(objRSAKey, "RSAOAEP") → "RSAOAEP"
1518  */
1519 /*
1520 KJUR.crypto.Cipher.getAlgByKeyAndName = function(keyObj, algName) {
1521     if (keyObj instanceof RSAKey) {
1522 	if (":RSA:RSAOAEP:RSAOAEP224:RSAOAEP256:RSAOAEP384:RSAOAEP512:".indexOf(algName) != -1)
1523 	    return algName;
1524 	if (algName === null || algName === undefined) return "RSA";
1525 	throw "getAlgByKeyAndName: not supported algorithm name for RSAKey: " + algName;
1526     }
1527     throw "getAlgByKeyAndName: not supported algorithm name: " + algName;
1528 }
1529  */
1530 
1531 // ====== Other Utility class =====================================================
1532 
1533 /**
1534  * static object for cryptographic function utilities
1535  * @name KJUR.crypto.OID
1536  * @class static object for cryptography related OIDs
1537  * @property {Array} oidhex2name key value of hexadecimal OID and its name
1538  *           (ex. '2a8648ce3d030107' and 'secp256r1')
1539  * @since crypto 1.1.3
1540  * @description
1541  */
1542 KJUR.crypto.OID = new function() {
1543     this.oidhex2name = {
1544 	'2a864886f70d010101': 'rsaEncryption',
1545 	'2a8648ce3d0201': 'ecPublicKey',
1546 	'2a8648ce380401': 'dsa',
1547 	'2a8648ce3d030107': 'secp256r1',
1548 	'2b8104001f': 'secp192k1',
1549 	'2b81040021': 'secp224r1',
1550 	'2b8104000a': 'secp256k1',
1551 	'2b81040022': 'secp384r1',
1552 	'2b81040023': 'secp521r1',
1553 	'2a8648ce380403': 'SHA1withDSA', // 1.2.840.10040.4.3
1554 	'608648016503040301': 'SHA224withDSA', // 2.16.840.1.101.3.4.3.1
1555 	'608648016503040302': 'SHA256withDSA', // 2.16.840.1.101.3.4.3.2
1556     };
1557 };
1558