12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136 |
- /*! crypto-1.1.6.js (c) 2013-2015 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
- /*
- * crypto.js - Cryptographic Algorithm Provider class
- *
- * Copyright (c) 2013-2015 Kenji Urushima (kenji.urushima@gmail.com)
- *
- * This software is licensed under the terms of the MIT License.
- * http://kjur.github.com/jsrsasign/license
- *
- * The above copyright and license notice shall be
- * included in all copies or substantial portions of the Software.
- */
- /**
- * @fileOverview
- * @name crypto-1.1.js
- * @author Kenji Urushima kenji.urushima@gmail.com
- * @version 1.1.6 (2015-Jun-07)
- * @since jsrsasign 2.2
- * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a>
- */
- /**
- * kjur's class library name space
- * @name KJUR
- * @namespace kjur's class library name space
- */
- if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
- /**
- * kjur's cryptographic algorithm provider library name space
- * <p>
- * This namespace privides following crytpgrahic classes.
- * <ul>
- * <li>{@link KJUR.crypto.MessageDigest} - Java JCE(cryptograhic extension) style MessageDigest class</li>
- * <li>{@link KJUR.crypto.Signature} - Java JCE(cryptograhic extension) style Signature class</li>
- * <li>{@link KJUR.crypto.Util} - cryptographic utility functions and properties</li>
- * </ul>
- * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
- * </p>
- * @name KJUR.crypto
- * @namespace
- */
- if (typeof KJUR.crypto == "undefined" || !KJUR.crypto) KJUR.crypto = {};
- /**
- * static object for cryptographic function utilities
- * @name KJUR.crypto.Util
- * @class static object for cryptographic function utilities
- * @property {Array} DIGESTINFOHEAD PKCS#1 DigestInfo heading hexadecimal bytes for each hash algorithms
- * @property {Array} DEFAULTPROVIDER associative array of default provider name for each hash and signature algorithms
- * @description
- */
- KJUR.crypto.Util = new function() {
- this.DIGESTINFOHEAD = {
- 'sha1': "3021300906052b0e03021a05000414",
- 'sha224': "302d300d06096086480165030402040500041c",
- 'sha256': "3031300d060960864801650304020105000420",
- 'sha384': "3041300d060960864801650304020205000430",
- 'sha512': "3051300d060960864801650304020305000440",
- 'md2': "3020300c06082a864886f70d020205000410",
- 'md5': "3020300c06082a864886f70d020505000410",
- 'ripemd160': "3021300906052b2403020105000414",
- };
- /**
- * @since crypto 1.1.1
- */
- this.DEFAULTPROVIDER = {
- 'md5': 'cryptojs',
- 'sha1': 'cryptojs',
- 'sha224': 'cryptojs',
- 'sha256': 'cryptojs',
- 'sha384': 'cryptojs',
- 'sha512': 'cryptojs',
- 'ripemd160': 'cryptojs',
- 'hmacmd5': 'cryptojs',
- 'hmacsha1': 'cryptojs',
- 'hmacsha224': 'cryptojs',
- 'hmacsha256': 'cryptojs',
- 'hmacsha384': 'cryptojs',
- 'hmacsha512': 'cryptojs',
- 'hmacripemd160': 'cryptojs',
- 'MD5withRSA': 'cryptojs/jsrsa',
- 'SHA1withRSA': 'cryptojs/jsrsa',
- 'SHA224withRSA': 'cryptojs/jsrsa',
- 'SHA256withRSA': 'cryptojs/jsrsa',
- 'SHA384withRSA': 'cryptojs/jsrsa',
- 'SHA512withRSA': 'cryptojs/jsrsa',
- 'RIPEMD160withRSA': 'cryptojs/jsrsa',
- 'MD5withECDSA': 'cryptojs/jsrsa',
- 'SHA1withECDSA': 'cryptojs/jsrsa',
- 'SHA224withECDSA': 'cryptojs/jsrsa',
- 'SHA256withECDSA': 'cryptojs/jsrsa',
- 'SHA384withECDSA': 'cryptojs/jsrsa',
- 'SHA512withECDSA': 'cryptojs/jsrsa',
- 'RIPEMD160withECDSA': 'cryptojs/jsrsa',
- 'SHA1withDSA': 'cryptojs/jsrsa',
- 'SHA224withDSA': 'cryptojs/jsrsa',
- 'SHA256withDSA': 'cryptojs/jsrsa',
- 'MD5withRSAandMGF1': 'cryptojs/jsrsa',
- 'SHA1withRSAandMGF1': 'cryptojs/jsrsa',
- 'SHA224withRSAandMGF1': 'cryptojs/jsrsa',
- 'SHA256withRSAandMGF1': 'cryptojs/jsrsa',
- 'SHA384withRSAandMGF1': 'cryptojs/jsrsa',
- 'SHA512withRSAandMGF1': 'cryptojs/jsrsa',
- 'RIPEMD160withRSAandMGF1': 'cryptojs/jsrsa',
- };
- /**
- * @since crypto 1.1.2
- */
- this.CRYPTOJSMESSAGEDIGESTNAME = {
- 'md5': 'CryptoJS.algo.MD5',
- 'sha1': 'CryptoJS.algo.SHA1',
- 'sha224': 'CryptoJS.algo.SHA224',
- 'sha256': 'CryptoJS.algo.SHA256',
- 'sha384': 'CryptoJS.algo.SHA384',
- 'sha512': 'CryptoJS.algo.SHA512',
- 'ripemd160': 'CryptoJS.algo.RIPEMD160'
- };
- /**
- * get hexadecimal DigestInfo
- * @name getDigestInfoHex
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} hHash hexadecimal hash value
- * @param {String} alg hash algorithm name (ex. 'sha1')
- * @return {String} hexadecimal string DigestInfo ASN.1 structure
- */
- this.getDigestInfoHex = function(hHash, alg) {
- if (typeof this.DIGESTINFOHEAD[alg] == "undefined")
- throw "alg not supported in Util.DIGESTINFOHEAD: " + alg;
- return this.DIGESTINFOHEAD[alg] + hHash;
- };
- /**
- * get PKCS#1 padded hexadecimal DigestInfo
- * @name getPaddedDigestInfoHex
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} hHash hexadecimal hash value of message to be signed
- * @param {String} alg hash algorithm name (ex. 'sha1')
- * @param {Integer} keySize key bit length (ex. 1024)
- * @return {String} hexadecimal string of PKCS#1 padded DigestInfo
- */
- this.getPaddedDigestInfoHex = function(hHash, alg, keySize) {
- var hDigestInfo = this.getDigestInfoHex(hHash, alg);
- var pmStrLen = keySize / 4; // minimum PM length
- if (hDigestInfo.length + 22 > pmStrLen) // len(0001+ff(*8)+00+hDigestInfo)=22
- throw "key is too short for SigAlg: keylen=" + keySize + "," + alg;
- var hHead = "0001";
- var hTail = "00" + hDigestInfo;
- var hMid = "";
- var fLen = pmStrLen - hHead.length - hTail.length;
- for (var i = 0; i < fLen; i += 2) {
- hMid += "ff";
- }
- var hPaddedMessage = hHead + hMid + hTail;
- return hPaddedMessage;
- };
- /**
- * get hexadecimal hash of string with specified algorithm
- * @name hashString
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} s input string to be hashed
- * @param {String} alg hash algorithm name
- * @return {String} hexadecimal string of hash value
- * @since 1.1.1
- */
- this.hashString = function(s, alg) {
- var md = new KJUR.crypto.MessageDigest({'alg': alg});
- return md.digestString(s);
- };
- /**
- * get hexadecimal hash of hexadecimal string with specified algorithm
- * @name hashHex
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} sHex input hexadecimal string to be hashed
- * @param {String} alg hash algorithm name
- * @return {String} hexadecimal string of hash value
- * @since 1.1.1
- */
- this.hashHex = function(sHex, alg) {
- var md = new KJUR.crypto.MessageDigest({'alg': alg});
- return md.digestHex(sHex);
- };
- /**
- * get hexadecimal SHA1 hash of string
- * @name sha1
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} s input string to be hashed
- * @return {String} hexadecimal string of hash value
- * @since 1.0.3
- */
- this.sha1 = function(s) {
- var md = new KJUR.crypto.MessageDigest({'alg':'sha1', 'prov':'cryptojs'});
- return md.digestString(s);
- };
- /**
- * get hexadecimal SHA256 hash of string
- * @name sha256
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} s input string to be hashed
- * @return {String} hexadecimal string of hash value
- * @since 1.0.3
- */
- this.sha256 = function(s) {
- var md = new KJUR.crypto.MessageDigest({'alg':'sha256', 'prov':'cryptojs'});
- return md.digestString(s);
- };
- this.sha256Hex = function(s) {
- var md = new KJUR.crypto.MessageDigest({'alg':'sha256', 'prov':'cryptojs'});
- return md.digestHex(s);
- };
- /**
- * get hexadecimal SHA512 hash of string
- * @name sha512
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} s input string to be hashed
- * @return {String} hexadecimal string of hash value
- * @since 1.0.3
- */
- this.sha512 = function(s) {
- var md = new KJUR.crypto.MessageDigest({'alg':'sha512', 'prov':'cryptojs'});
- return md.digestString(s);
- };
- this.sha512Hex = function(s) {
- var md = new KJUR.crypto.MessageDigest({'alg':'sha512', 'prov':'cryptojs'});
- return md.digestHex(s);
- };
- /**
- * get hexadecimal MD5 hash of string
- * @name md5
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} s input string to be hashed
- * @return {String} hexadecimal string of hash value
- * @since 1.0.3
- */
- this.md5 = function(s) {
- var md = new KJUR.crypto.MessageDigest({'alg':'md5', 'prov':'cryptojs'});
- return md.digestString(s);
- };
- /**
- * get hexadecimal RIPEMD160 hash of string
- * @name ripemd160
- * @memberOf KJUR.crypto.Util
- * @function
- * @param {String} s input string to be hashed
- * @return {String} hexadecimal string of hash value
- * @since 1.0.3
- */
- this.ripemd160 = function(s) {
- var md = new KJUR.crypto.MessageDigest({'alg':'ripemd160', 'prov':'cryptojs'});
- return md.digestString(s);
- };
- /**
- * @since 1.1.2
- */
- this.getCryptoJSMDByName = function(s) {
-
- };
- };
- /**
- * MessageDigest class which is very similar to java.security.MessageDigest class
- * @name KJUR.crypto.MessageDigest
- * @class MessageDigest class which is very similar to java.security.MessageDigest class
- * @param {Array} params parameters for constructor
- * @description
- * <br/>
- * Currently this supports following algorithm and providers combination:
- * <ul>
- * <li>md5 - cryptojs</li>
- * <li>sha1 - cryptojs</li>
- * <li>sha224 - cryptojs</li>
- * <li>sha256 - cryptojs</li>
- * <li>sha384 - cryptojs</li>
- * <li>sha512 - cryptojs</li>
- * <li>ripemd160 - cryptojs</li>
- * <li>sha256 - sjcl (NEW from crypto.js 1.0.4)</li>
- * </ul>
- * @example
- * // CryptoJS provider sample
- * var md = new KJUR.crypto.MessageDigest({alg: "sha1", prov: "cryptojs"});
- * md.updateString('aaa')
- * var mdHex = md.digest()
- *
- * // SJCL(Stanford JavaScript Crypto Library) provider sample
- * var md = new KJUR.crypto.MessageDigest({alg: "sha256", prov: "sjcl"}); // sjcl supports sha256 only
- * md.updateString('aaa')
- * var mdHex = md.digest()
- */
- KJUR.crypto.MessageDigest = function(params) {
- var md = null;
- var algName = null;
- var provName = null;
- /**
- * set hash algorithm and provider
- * @name setAlgAndProvider
- * @memberOf KJUR.crypto.MessageDigest
- * @function
- * @param {String} alg hash algorithm name
- * @param {String} prov provider name
- * @description
- * @example
- * // for SHA1
- * md.setAlgAndProvider('sha1', 'cryptojs');
- * // for RIPEMD160
- * md.setAlgAndProvider('ripemd160', 'cryptojs');
- */
- this.setAlgAndProvider = function(alg, prov) {
- if (alg != null && prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];
- // for cryptojs
- if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(alg) != -1 &&
- prov == 'cryptojs') {
- try {
- this.md = eval(KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[alg]).create();
- } catch (ex) {
- throw "setAlgAndProvider hash alg set fail alg=" + alg + "/" + ex;
- }
- this.updateString = function(str) {
- this.md.update(str);
- };
- this.updateHex = function(hex) {
- var wHex = CryptoJS.enc.Hex.parse(hex);
- this.md.update(wHex);
- };
- this.digest = function() {
- var hash = this.md.finalize();
- return hash.toString(CryptoJS.enc.Hex);
- };
- this.digestString = function(str) {
- this.updateString(str);
- return this.digest();
- };
- this.digestHex = function(hex) {
- this.updateHex(hex);
- return this.digest();
- };
- }
- if (':sha256:'.indexOf(alg) != -1 &&
- prov == 'sjcl') {
- try {
- this.md = new sjcl.hash.sha256();
- } catch (ex) {
- throw "setAlgAndProvider hash alg set fail alg=" + alg + "/" + ex;
- }
- this.updateString = function(str) {
- this.md.update(str);
- };
- this.updateHex = function(hex) {
- var baHex = sjcl.codec.hex.toBits(hex);
- this.md.update(baHex);
- };
- this.digest = function() {
- var hash = this.md.finalize();
- return sjcl.codec.hex.fromBits(hash);
- };
- this.digestString = function(str) {
- this.updateString(str);
- return this.digest();
- };
- this.digestHex = function(hex) {
- this.updateHex(hex);
- return this.digest();
- };
- }
- };
- /**
- * update digest by specified string
- * @name updateString
- * @memberOf KJUR.crypto.MessageDigest
- * @function
- * @param {String} str string to update
- * @description
- * @example
- * md.updateString('New York');
- */
- this.updateString = function(str) {
- throw "updateString(str) not supported for this alg/prov: " + this.algName + "/" + this.provName;
- };
- /**
- * update digest by specified hexadecimal string
- * @name updateHex
- * @memberOf KJUR.crypto.MessageDigest
- * @function
- * @param {String} hex hexadecimal string to update
- * @description
- * @example
- * md.updateHex('0afe36');
- */
- this.updateHex = function(hex) {
- throw "updateHex(hex) not supported for this alg/prov: " + this.algName + "/" + this.provName;
- };
- /**
- * completes hash calculation and returns hash result
- * @name digest
- * @memberOf KJUR.crypto.MessageDigest
- * @function
- * @description
- * @example
- * md.digest()
- */
- this.digest = function() {
- throw "digest() not supported for this alg/prov: " + this.algName + "/" + this.provName;
- };
- /**
- * performs final update on the digest using string, then completes the digest computation
- * @name digestString
- * @memberOf KJUR.crypto.MessageDigest
- * @function
- * @param {String} str string to final update
- * @description
- * @example
- * md.digestString('aaa')
- */
- this.digestString = function(str) {
- throw "digestString(str) not supported for this alg/prov: " + this.algName + "/" + this.provName;
- };
- /**
- * performs final update on the digest using hexadecimal string, then completes the digest computation
- * @name digestHex
- * @memberOf KJUR.crypto.MessageDigest
- * @function
- * @param {String} hex hexadecimal string to final update
- * @description
- * @example
- * md.digestHex('0f2abd')
- */
- this.digestHex = function(hex) {
- throw "digestHex(hex) not supported for this alg/prov: " + this.algName + "/" + this.provName;
- };
- if (params !== undefined) {
- if (params['alg'] !== undefined) {
- this.algName = params['alg'];
- if (params['prov'] === undefined)
- this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
- this.setAlgAndProvider(this.algName, this.provName);
- }
- }
- };
- /**
- * Mac(Message Authentication Code) class which is very similar to java.security.Mac class
- * @name KJUR.crypto.Mac
- * @class Mac class which is very similar to java.security.Mac class
- * @param {Array} params parameters for constructor
- * @description
- * <br/>
- * Currently this supports following algorithm and providers combination:
- * <ul>
- * <li>hmacmd5 - cryptojs</li>
- * <li>hmacsha1 - cryptojs</li>
- * <li>hmacsha224 - cryptojs</li>
- * <li>hmacsha256 - cryptojs</li>
- * <li>hmacsha384 - cryptojs</li>
- * <li>hmacsha512 - cryptojs</li>
- * </ul>
- * NOTE: HmacSHA224 and HmacSHA384 issue was fixed since jsrsasign 4.1.4.
- * Please use 'ext/cryptojs-312-core-fix*.js' instead of 'core.js' of original CryptoJS
- * to avoid those issue.
- * @example
- * var mac = new KJUR.crypto.Mac({alg: "HmacSHA1", prov: "cryptojs", "pass": "pass"});
- * mac.updateString('aaa')
- * var macHex = md.doFinal()
- */
- KJUR.crypto.Mac = function(params) {
- var mac = null;
- var pass = null;
- var algName = null;
- var provName = null;
- var algProv = null;
- this.setAlgAndProvider = function(alg, prov) {
- if (alg == null) alg = "hmacsha1";
- alg = alg.toLowerCase();
- if (alg.substr(0, 4) != "hmac") {
- throw "setAlgAndProvider unsupported HMAC alg: " + alg;
- }
- if (prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];
- this.algProv = alg + "/" + prov;
- var hashAlg = alg.substr(4);
- // for cryptojs
- if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(hashAlg) != -1 &&
- prov == 'cryptojs') {
- try {
- var mdObj = eval(KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[hashAlg]);
- this.mac = CryptoJS.algo.HMAC.create(mdObj, this.pass);
- } catch (ex) {
- throw "setAlgAndProvider hash alg set fail hashAlg=" + hashAlg + "/" + ex;
- }
- this.updateString = function(str) {
- this.mac.update(str);
- };
- this.updateHex = function(hex) {
- var wHex = CryptoJS.enc.Hex.parse(hex);
- this.mac.update(wHex);
- };
- this.doFinal = function() {
- var hash = this.mac.finalize();
- return hash.toString(CryptoJS.enc.Hex);
- };
- this.doFinalString = function(str) {
- this.updateString(str);
- return this.doFinal();
- };
- this.doFinalHex = function(hex) {
- this.updateHex(hex);
- return this.doFinal();
- };
- }
- };
- /**
- * update digest by specified string
- * @name updateString
- * @memberOf KJUR.crypto.Mac
- * @function
- * @param {String} str string to update
- * @description
- * @example
- * md.updateString('New York');
- */
- this.updateString = function(str) {
- throw "updateString(str) not supported for this alg/prov: " + this.algProv;
- };
- /**
- * update digest by specified hexadecimal string
- * @name updateHex
- * @memberOf KJUR.crypto.Mac
- * @function
- * @param {String} hex hexadecimal string to update
- * @description
- * @example
- * md.updateHex('0afe36');
- */
- this.updateHex = function(hex) {
- throw "updateHex(hex) not supported for this alg/prov: " + this.algProv;
- };
- /**
- * completes hash calculation and returns hash result
- * @name doFinal
- * @memberOf KJUR.crypto.Mac
- * @function
- * @description
- * @example
- * md.digest()
- */
- this.doFinal = function() {
- throw "digest() not supported for this alg/prov: " + this.algProv;
- };
- /**
- * performs final update on the digest using string, then completes the digest computation
- * @name doFinalString
- * @memberOf KJUR.crypto.Mac
- * @function
- * @param {String} str string to final update
- * @description
- * @example
- * md.digestString('aaa')
- */
- this.doFinalString = function(str) {
- throw "digestString(str) not supported for this alg/prov: " + this.algProv;
- };
- /**
- * performs final update on the digest using hexadecimal string,
- * then completes the digest computation
- * @name doFinalHex
- * @memberOf KJUR.crypto.Mac
- * @function
- * @param {String} hex hexadecimal string to final update
- * @description
- * @example
- * md.digestHex('0f2abd')
- */
- this.doFinalHex = function(hex) {
- throw "digestHex(hex) not supported for this alg/prov: " + this.algProv;
- };
- if (params !== undefined) {
- if (params['pass'] !== undefined) {
- this.pass = params['pass'];
- }
- if (params['alg'] !== undefined) {
- this.algName = params['alg'];
- if (params['prov'] === undefined)
- this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
- this.setAlgAndProvider(this.algName, this.provName);
- }
- }
- };
- /**
- * Signature class which is very similar to java.security.Signature class
- * @name KJUR.crypto.Signature
- * @class Signature class which is very similar to java.security.Signature class
- * @param {Array} params parameters for constructor
- * @property {String} state Current state of this signature object whether 'SIGN', 'VERIFY' or null
- * @description
- * <br/>
- * As for params of constructor's argument, it can be specify following attributes:
- * <ul>
- * <li>alg - signature algorithm name (ex. {MD5,SHA1,SHA224,SHA256,SHA384,SHA512,RIPEMD160}with{RSA,ECDSA,DSA})</li>
- * <li>provider - currently 'cryptojs/jsrsa' only</li>
- * </ul>
- * <h4>SUPPORTED ALGORITHMS AND PROVIDERS</h4>
- * This Signature class supports following signature algorithm and provider names:
- * <ul>
- * <li>MD5withRSA - cryptojs/jsrsa</li>
- * <li>SHA1withRSA - cryptojs/jsrsa</li>
- * <li>SHA224withRSA - cryptojs/jsrsa</li>
- * <li>SHA256withRSA - cryptojs/jsrsa</li>
- * <li>SHA384withRSA - cryptojs/jsrsa</li>
- * <li>SHA512withRSA - cryptojs/jsrsa</li>
- * <li>RIPEMD160withRSA - cryptojs/jsrsa</li>
- * <li>MD5withECDSA - cryptojs/jsrsa</li>
- * <li>SHA1withECDSA - cryptojs/jsrsa</li>
- * <li>SHA224withECDSA - cryptojs/jsrsa</li>
- * <li>SHA256withECDSA - cryptojs/jsrsa</li>
- * <li>SHA384withECDSA - cryptojs/jsrsa</li>
- * <li>SHA512withECDSA - cryptojs/jsrsa</li>
- * <li>RIPEMD160withECDSA - cryptojs/jsrsa</li>
- * <li>MD5withRSAandMGF1 - cryptojs/jsrsa</li>
- * <li>SHA1withRSAandMGF1 - cryptojs/jsrsa</li>
- * <li>SHA224withRSAandMGF1 - cryptojs/jsrsa</li>
- * <li>SHA256withRSAandMGF1 - cryptojs/jsrsa</li>
- * <li>SHA384withRSAandMGF1 - cryptojs/jsrsa</li>
- * <li>SHA512withRSAandMGF1 - cryptojs/jsrsa</li>
- * <li>RIPEMD160withRSAandMGF1 - cryptojs/jsrsa</li>
- * <li>SHA1withDSA - cryptojs/jsrsa</li>
- * <li>SHA224withDSA - cryptojs/jsrsa</li>
- * <li>SHA256withDSA - cryptojs/jsrsa</li>
- * </ul>
- * Here are supported elliptic cryptographic curve names and their aliases for ECDSA:
- * <ul>
- * <li>secp256k1</li>
- * <li>secp256r1, NIST P-256, P-256, prime256v1</li>
- * <li>secp384r1, NIST P-384, P-384</li>
- * </ul>
- * NOTE1: DSA signing algorithm is also supported since crypto 1.1.5.
- * <h4>EXAMPLES</h4>
- * @example
- * // RSA signature generation
- * var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"});
- * sig.init(prvKeyPEM);
- * sig.updateString('aaa');
- * var hSigVal = sig.sign();
- *
- * // DSA signature validation
- * var sig2 = new KJUR.crypto.Signature({"alg": "SHA1withDSA"});
- * sig2.init(certPEM);
- * sig.updateString('aaa');
- * var isValid = sig2.verify(hSigVal);
- *
- * // ECDSA signing
- * var sig = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});
- * sig.init(prvKeyPEM);
- * sig.updateString('aaa');
- * var sigValueHex = sig.sign();
- *
- * // ECDSA verifying
- * var sig2 = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});
- * sig.init(certPEM);
- * sig.updateString('aaa');
- * var isValid = sig.verify(sigValueHex);
- */
- KJUR.crypto.Signature = function(params) {
- var prvKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for signing
- var pubKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for verifying
- var md = null; // KJUR.crypto.MessageDigest object
- var sig = null;
- var algName = null;
- var provName = null;
- var algProvName = null;
- var mdAlgName = null;
- var pubkeyAlgName = null; // rsa,ecdsa,rsaandmgf1(=rsapss)
- var state = null;
- var pssSaltLen = -1;
- var initParams = null;
- var sHashHex = null; // hex hash value for hex
- var hDigestInfo = null;
- var hPaddedDigestInfo = null;
- var hSign = null;
- this._setAlgNames = function() {
- if (this.algName.match(/^(.+)with(.+)$/)) {
- this.mdAlgName = RegExp.$1.toLowerCase();
- this.pubkeyAlgName = RegExp.$2.toLowerCase();
- }
- };
- this._zeroPaddingOfSignature = function(hex, bitLength) {
- var s = "";
- var nZero = bitLength / 4 - hex.length;
- for (var i = 0; i < nZero; i++) {
- s = s + "0";
- }
- return s + hex;
- };
- /**
- * set signature algorithm and provider
- * @name setAlgAndProvider
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {String} alg signature algorithm name
- * @param {String} prov provider name
- * @description
- * @example
- * md.setAlgAndProvider('SHA1withRSA', 'cryptojs/jsrsa');
- */
- this.setAlgAndProvider = function(alg, prov) {
- this._setAlgNames();
- if (prov != 'cryptojs/jsrsa')
- throw "provider not supported: " + prov;
- if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(this.mdAlgName) != -1) {
- try {
- this.md = new KJUR.crypto.MessageDigest({'alg':this.mdAlgName});
- } catch (ex) {
- throw "setAlgAndProvider hash alg set fail alg=" +
- this.mdAlgName + "/" + ex;
- }
- this.init = function(keyparam, pass) {
- var keyObj = null;
- try {
- if (pass === undefined) {
- keyObj = KEYUTIL.getKey(keyparam);
- } else {
- keyObj = KEYUTIL.getKey(keyparam, pass);
- }
- } catch (ex) {
- throw "init failed:" + ex;
- }
- if (keyObj.isPrivate === true) {
- this.prvKey = keyObj;
- this.state = "SIGN";
- } else if (keyObj.isPublic === true) {
- this.pubKey = keyObj;
- this.state = "VERIFY";
- } else {
- throw "init failed.:" + keyObj;
- }
- };
- this.initSign = function(params) {
- if (typeof params['ecprvhex'] == 'string' &&
- typeof params['eccurvename'] == 'string') {
- this.ecprvhex = params['ecprvhex'];
- this.eccurvename = params['eccurvename'];
- } else {
- this.prvKey = params;
- }
- this.state = "SIGN";
- };
- this.initVerifyByPublicKey = function(params) {
- if (typeof params['ecpubhex'] == 'string' &&
- typeof params['eccurvename'] == 'string') {
- this.ecpubhex = params['ecpubhex'];
- this.eccurvename = params['eccurvename'];
- } else if (params instanceof KJUR.crypto.ECDSA) {
- this.pubKey = params;
- } else if (params instanceof RSAKey) {
- this.pubKey = params;
- }
- this.state = "VERIFY";
- };
- this.initVerifyByCertificatePEM = function(certPEM) {
- var x509 = new X509();
- x509.readCertPEM(certPEM);
- this.pubKey = x509.subjectPublicKeyRSA;
- this.state = "VERIFY";
- };
- this.updateString = function(str) {
- this.md.updateString(str);
- };
- this.updateHex = function(hex) {
- this.md.updateHex(hex);
- };
- this.sign = function() {
- this.sHashHex = this.md.digest();
- if (typeof this.ecprvhex != "undefined" &&
- typeof this.eccurvename != "undefined") {
- var ec = new KJUR.crypto.ECDSA({'curve': this.eccurvename});
- this.hSign = ec.signHex(this.sHashHex, this.ecprvhex);
- } else if (this.prvKey instanceof RSAKey &&
- this.pubkeyAlgName == "rsaandmgf1") {
- this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex,
- this.mdAlgName,
- this.pssSaltLen);
- } else if (this.prvKey instanceof RSAKey &&
- this.pubkeyAlgName == "rsa") {
- this.hSign = this.prvKey.signWithMessageHash(this.sHashHex,
- this.mdAlgName);
- } else if (this.prvKey instanceof KJUR.crypto.ECDSA) {
- this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);
- } else if (this.prvKey instanceof KJUR.crypto.DSA) {
- this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);
- } else {
- throw "Signature: unsupported public key alg: " + this.pubkeyAlgName;
- }
- return this.hSign;
- };
- this.signString = function(str) {
- this.updateString(str);
- return this.sign();
- };
- this.signHex = function(hex) {
- this.updateHex(hex);
- return this.sign();
- };
- this.verify = function(hSigVal) {
- this.sHashHex = this.md.digest();
- if (typeof this.ecpubhex != "undefined" &&
- typeof this.eccurvename != "undefined") {
- var ec = new KJUR.crypto.ECDSA({curve: this.eccurvename});
- return ec.verifyHex(this.sHashHex, hSigVal, this.ecpubhex);
- } else if (this.pubKey instanceof RSAKey &&
- this.pubkeyAlgName == "rsaandmgf1") {
- return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, hSigVal,
- this.mdAlgName,
- this.pssSaltLen);
- } else if (this.pubKey instanceof RSAKey &&
- this.pubkeyAlgName == "rsa") {
- return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
- } else if (this.pubKey instanceof KJUR.crypto.ECDSA) {
- return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
- } else if (this.pubKey instanceof KJUR.crypto.DSA) {
- return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
- } else {
- throw "Signature: unsupported public key alg: " + this.pubkeyAlgName;
- }
- };
- }
- };
- /**
- * Initialize this object for signing or verifying depends on key
- * @name init
- * @memberOf KJUR.crypto.Signature
- * @function
- * @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
- * @param {String} pass (OPTION) passcode for encrypted private key
- * @since crypto 1.1.3
- * @description
- * This method is very useful initialize method for Signature class since
- * you just specify key then this method will automatically initialize it
- * using {@link KEYUTIL.getKey} method.
- * As for 'key', following argument type are supported:
- * <h5>signing</h5>
- * <ul>
- * <li>PEM formatted PKCS#8 encrypted RSA/ECDSA private key concluding "BEGIN ENCRYPTED PRIVATE KEY"</li>
- * <li>PEM formatted PKCS#5 encrypted RSA/DSA private key concluding "BEGIN RSA/DSA PRIVATE KEY" and ",ENCRYPTED"</li>
- * <li>PEM formatted PKCS#8 plain RSA/ECDSA private key concluding "BEGIN PRIVATE KEY"</li>
- * <li>PEM formatted PKCS#5 plain RSA/DSA private key concluding "BEGIN RSA/DSA PRIVATE KEY" without ",ENCRYPTED"</li>
- * <li>RSAKey object of private key</li>
- * <li>KJUR.crypto.ECDSA object of private key</li>
- * <li>KJUR.crypto.DSA object of private key</li>
- * </ul>
- * <h5>verification</h5>
- * <ul>
- * <li>PEM formatted PKCS#8 RSA/EC/DSA public key concluding "BEGIN PUBLIC KEY"</li>
- * <li>PEM formatted X.509 certificate with RSA/EC/DSA public key concluding
- * "BEGIN CERTIFICATE", "BEGIN X509 CERTIFICATE" or "BEGIN TRUSTED CERTIFICATE".</li>
- * <li>RSAKey object of public key</li>
- * <li>KJUR.crypto.ECDSA object of public key</li>
- * <li>KJUR.crypto.DSA object of public key</li>
- * </ul>
- * @example
- * sig.init(sCertPEM)
- */
- this.init = function(key, pass) {
- throw "init(key, pass) not supported for this alg:prov=" +
- this.algProvName;
- };
- /**
- * Initialize this object for verifying with a public key
- * @name initVerifyByPublicKey
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {Object} param RSAKey object of public key or associative array for ECDSA
- * @since 1.0.2
- * @deprecated from crypto 1.1.5. please use init() method instead.
- * @description
- * Public key information will be provided as 'param' parameter and the value will be
- * following:
- * <ul>
- * <li>{@link RSAKey} object for RSA verification</li>
- * <li>associative array for ECDSA verification
- * (ex. <code>{'ecpubhex': '041f..', 'eccurvename': 'secp256r1'}</code>)
- * </li>
- * </ul>
- * @example
- * sig.initVerifyByPublicKey(rsaPrvKey)
- */
- this.initVerifyByPublicKey = function(rsaPubKey) {
- throw "initVerifyByPublicKey(rsaPubKeyy) not supported for this alg:prov=" +
- this.algProvName;
- };
- /**
- * Initialize this object for verifying with a certficate
- * @name initVerifyByCertificatePEM
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {String} certPEM PEM formatted string of certificate
- * @since 1.0.2
- * @deprecated from crypto 1.1.5. please use init() method instead.
- * @description
- * @example
- * sig.initVerifyByCertificatePEM(certPEM)
- */
- this.initVerifyByCertificatePEM = function(certPEM) {
- throw "initVerifyByCertificatePEM(certPEM) not supported for this alg:prov=" +
- this.algProvName;
- };
- /**
- * Initialize this object for signing
- * @name initSign
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {Object} param RSAKey object of public key or associative array for ECDSA
- * @deprecated from crypto 1.1.5. please use init() method instead.
- * @description
- * Private key information will be provided as 'param' parameter and the value will be
- * following:
- * <ul>
- * <li>{@link RSAKey} object for RSA signing</li>
- * <li>associative array for ECDSA signing
- * (ex. <code>{'ecprvhex': '1d3f..', 'eccurvename': 'secp256r1'}</code>)</li>
- * </ul>
- * @example
- * sig.initSign(prvKey)
- */
- this.initSign = function(prvKey) {
- throw "initSign(prvKey) not supported for this alg:prov=" + this.algProvName;
- };
- /**
- * Updates the data to be signed or verified by a string
- * @name updateString
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {String} str string to use for the update
- * @description
- * @example
- * sig.updateString('aaa')
- */
- this.updateString = function(str) {
- throw "updateString(str) not supported for this alg:prov=" + this.algProvName;
- };
- /**
- * Updates the data to be signed or verified by a hexadecimal string
- * @name updateHex
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {String} hex hexadecimal string to use for the update
- * @description
- * @example
- * sig.updateHex('1f2f3f')
- */
- this.updateHex = function(hex) {
- throw "updateHex(hex) not supported for this alg:prov=" + this.algProvName;
- };
- /**
- * Returns the signature bytes of all data updates as a hexadecimal string
- * @name sign
- * @memberOf KJUR.crypto.Signature
- * @function
- * @return the signature bytes as a hexadecimal string
- * @description
- * @example
- * var hSigValue = sig.sign()
- */
- this.sign = function() {
- throw "sign() not supported for this alg:prov=" + this.algProvName;
- };
- /**
- * performs final update on the sign using string, then returns the signature bytes of all data updates as a hexadecimal string
- * @name signString
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {String} str string to final update
- * @return the signature bytes of a hexadecimal string
- * @description
- * @example
- * var hSigValue = sig.signString('aaa')
- */
- this.signString = function(str) {
- throw "digestString(str) not supported for this alg:prov=" + this.algProvName;
- };
- /**
- * performs final update on the sign using hexadecimal string, then returns the signature bytes of all data updates as a hexadecimal string
- * @name signHex
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {String} hex hexadecimal string to final update
- * @return the signature bytes of a hexadecimal string
- * @description
- * @example
- * var hSigValue = sig.signHex('1fdc33')
- */
- this.signHex = function(hex) {
- throw "digestHex(hex) not supported for this alg:prov=" + this.algProvName;
- };
- /**
- * verifies the passed-in signature.
- * @name verify
- * @memberOf KJUR.crypto.Signature
- * @function
- * @param {String} str string to final update
- * @return {Boolean} true if the signature was verified, otherwise false
- * @description
- * @example
- * var isValid = sig.verify('1fbcefdca4823a7(snip)')
- */
- this.verify = function(hSigVal) {
- throw "verify(hSigVal) not supported for this alg:prov=" + this.algProvName;
- };
- this.initParams = params;
- if (params !== undefined) {
- if (params['alg'] !== undefined) {
- this.algName = params['alg'];
- if (params['prov'] === undefined) {
- this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
- } else {
- this.provName = params['prov'];
- }
- this.algProvName = this.algName + ":" + this.provName;
- this.setAlgAndProvider(this.algName, this.provName);
- this._setAlgNames();
- }
- if (params['psssaltlen'] !== undefined) this.pssSaltLen = params['psssaltlen'];
- if (params['prvkeypem'] !== undefined) {
- if (params['prvkeypas'] !== undefined) {
- throw "both prvkeypem and prvkeypas parameters not supported";
- } else {
- try {
- var prvKey = new RSAKey();
- prvKey.readPrivateKeyFromPEMString(params['prvkeypem']);
- this.initSign(prvKey);
- } catch (ex) {
- throw "fatal error to load pem private key: " + ex;
- }
- }
- }
- }
- };
- /**
- * static object for cryptographic function utilities
- * @name KJUR.crypto.OID
- * @class static object for cryptography related OIDs
- * @property {Array} oidhex2name key value of hexadecimal OID and its name
- * (ex. '2a8648ce3d030107' and 'secp256r1')
- * @since crypto 1.1.3
- * @description
- */
- KJUR.crypto.OID = new function() {
- this.oidhex2name = {
- '2a864886f70d010101': 'rsaEncryption',
- '2a8648ce3d0201': 'ecPublicKey',
- '2a8648ce380401': 'dsa',
- '2a8648ce3d030107': 'secp256r1',
- '2b8104001f': 'secp192k1',
- '2b81040021': 'secp224r1',
- '2b8104000a': 'secp256k1',
- '2b81040023': 'secp521r1',
- '2b81040022': 'secp384r1',
- '2a8648ce380403': 'SHA1withDSA', // 1.2.840.10040.4.3
- '608648016503040301': 'SHA224withDSA', // 2.16.840.1.101.3.4.3.1
- '608648016503040302': 'SHA256withDSA', // 2.16.840.1.101.3.4.3.2
- };
- };
|