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