/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* encrypt2 implementation in JavaScript (c) Chris Veness 2005-2011 */ /* - see http://csrc.nist.gov/publications/PubsFIPS.html#197 */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ var encrypt2 = {}; // encrypt2 namespace /** * encrypt2 Cipher function: encrypt 'input' state with Rijndael algorithm * applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage * * @param {Number[]} input 16-byte (128-bit) input state array * @param {Number[][]} w Key schedule as 2D byte-array (Nr+1 x Nb bytes) * @returns {Number[]} Encrypted output state array */ encrypt2.cipher = function(input, w) { // main Cipher function [§5.1] var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for encrypt2) var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys var state = [[],[],[],[]]; // initialise 4xNb byte-array 'state' with input [§3.4] for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i]; state = encrypt2.addRoundKey(state, w, 0, Nb); for (var round=1; round 6 && i%Nk == 4) { temp = encrypt2.subWord(temp); } for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t]; } return w; } /* * ---- remaining routines are private, not called externally ---- */ encrypt2.subBytes = function(s, Nb) { // apply SBox to state S [§5.1.1] for (var r=0; r<4; r++) { for (var c=0; c>> i*8) & 0xff; for (var i=0; i<2; i++) counterBlock[i+2] = (nonceRnd >>> i*8) & 0xff; for (var i=0; i<4; i++) counterBlock[i+4] = (nonceSec >>> i*8) & 0xff; // and convert it to a string to go on the front of the ciphertext var ctrTxt = ''; for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]); // generate key schedule - an expansion of the key into distinct Key Rounds for each round var keySchedule = encrypt2.keyExpansion(key); var blockCount = Math.ceil(plaintext.length/blockSize); var ciphertxt = new Array(blockCount); // ciphertext as array of strings for (var b=0; b>> c*8) & 0xff; for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8) var cipherCntr = encrypt2.cipher(counterBlock, keySchedule); // -- encrypt counter block -- // block size is reduced on final block var blockLength = b>> c*8) & 0xff; for (var c=0; c<4; c++) counterBlock[15-c-4] = (((b+1)/0x100000000-1) >>> c*8) & 0xff; var cipherCntr = encrypt2.cipher(counterBlock, keySchedule); // encrypt counter block var plaintxtByte = new Array(ciphertext[b].length); for (var i=0; i 0) { while (c++ < 3) { pad += '='; plain += '\0'; } } // note: doing padding here saves us doing special-case packing for trailing 1 or 2 chars for (c=0; c>18 & 0x3f; h2 = bits>>12 & 0x3f; h3 = bits>>6 & 0x3f; h4 = bits & 0x3f; // use hextets to index into code string e[c/3] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); } coded = e.join(''); // join() is far faster than repeated string concatenation in IE // replace 'A's from padded nulls with '='s coded = coded.slice(0, coded.length-pad.length) + pad; return coded; } /** * Decode string from Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648] * (instance method extending String object). As per RFC 4648, newlines are not catered for. * * @param {String} str The string to be decoded from base-64 * @param {Boolean} [utf8decode=false] Flag to indicate whether str is Unicode string to be decoded * from UTF8 after conversion from base64 * @returns {String} decoded string */ Base64.decode = function(str, utf8decode) { utf8decode = (typeof utf8decode == 'undefined') ? false : utf8decode; var o1, o2, o3, h1, h2, h3, h4, bits, d=[], plain, coded; var b64 = Base64.code; coded = utf8decode ? str.decodeUTF8() : str; for (var c=0; c>>16 & 0xff; o2 = bits>>>8 & 0xff; o3 = bits & 0xff; d[c/4] = String.fromCharCode(o1, o2, o3); // check for padding if (h4 == 0x40) d[c/4] = String.fromCharCode(o1, o2); if (h3 == 0x40) d[c/4] = String.fromCharCode(o1); } plain = d.join(''); // join() is far faster than repeated string concatenation in IE return utf8decode ? plain.decodeUTF8() : plain; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple */ /* single-byte character encoding (c) Chris Veness 2002-2011 */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ var Utf8 = {}; // Utf8 namespace /** * Encode multi-byte Unicode string into utf-8 multiple single-byte characters * (BMP / basic multilingual plane only) * * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars * * @param {String} strUni Unicode string to be encoded as UTF-8 * @returns {String} encoded string */ Utf8.encode = function(strUni) { // use regular expressions & String.replace callback function for better efficiency // than procedural approaches var strUtf = strUni.replace( /[\u0080-\u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz function(c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); } ); strUtf = strUtf.replace( /[\u0800-\uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz function(c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); } ); return strUtf; } /** * Decode utf-8 encoded string back into multi-byte Unicode characters * * @param {String} strUtf UTF-8 string to be decoded back to Unicode * @returns {String} decoded string */ Utf8.decode = function(strUtf) { // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char! var strUni = strUtf.replace( /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars function(c) { // (note parentheses for precence) var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f); return String.fromCharCode(cc); } ); strUni = strUni.replace( /[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars function(c) { // (note parentheses for precence) var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f; return String.fromCharCode(cc); } ); return strUni; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ function getSsoUid(){ if(null == readCookie("uid2") ||""==readCookie("uid2")|| null == readCookie("uid1")||""==readCookie("uid1")){ return ""; } return encrypt2.Ctr.decrypt(unescape(readCookie("uid2")), readCookie("uid1")); } function setSsoUid(){ var t = new Date().getTime(); var uid1 = ""+t; createCookie("uid1",uid1,null,"/"); var uid2 = escape(encrypt2.Ctr.encrypt(frm.PASSWORD1.value, uid1+"ceauy")); createCookie("uid2",uid2,null,"/"); createCookie("LOGINID",document.frm.LOGINID.value,null,"/"); } function ssoLogin(serverUrl,loginid,uid,func){ if('[object Function]' != Object.prototype.toString.call(func)){ func = function(){}; } var msgObj = showMsg('正在单点登陆',-1); var url = serverUrl+"/index_sso.jsp"; jsonpRequest(url,{},function(data){ if('CONFIRMERROR' == data.LOGINSTATE && null != data.ERRORID){ var _uid = stringToHex(encrypt(data.ERRORID,uid)); jsonpRequest(url,{LOGINID:loginid,UID:_uid,SID:data.SID}, function(data){ hideMsg(msgObj); func(data); } ); }else{ hideMsg(msgObj); func(data); } },msgObj//function ); } function jsonpRequest(url,data,func,msgObj){ if('[object Function]' != Object.prototype.toString.call(func)){ func = function(){}; } //利用ajax.js的函数添加提示信息 //var msgObj = showMsg('正在...',-1); if(null == window.fwJsonpCallbackId){ window.fwJsonpCallbackId = 0; } if(null == window.fwJsonpData){ window.fwJsonpData = {}; } var jsonpScript = document.createElement("script"); //jsonp回调函数 jsonpScript.onreadystatechange = function(){ //JSONP回调的响应顺序为:complete->window["fwJsonpCallback"+curFwJsonpCallbackId]->loaded if('complete' == this.readyState ||'loaded' == this.readyState){ this.onreadystatechange = null; if(null == window.fwJsonpData[""+curFwJsonpCallbackId]){ alert("服务器"+getServerUrl(url)+"没有返回数据"); if(msgObj!=null){ hideMsg(msgObj); } }else{ func(window.fwJsonpData[""+curFwJsonpCallbackId]); } //删除全局变量的数据 delete window.fwJsonpData[""+curFwJsonpCallbackId]; //删除创建的script。经Drip.exe测试,由于IE的设计,实际并不能删除 //jsonpScript.onreadystatechange = null; //document.getElementsByTagName("head")[0].removeChild(jsonpScript); } } //在url末尾加上参数 var query = ""; for(var key in data){ query += "&" + key + "=" + encodeURIComponent(data[key]); } var curFwJsonpCallbackId = ++window.fwJsonpCallbackId; query += "&callback="+"fwJsonpCallback"+(curFwJsonpCallbackId); query += "&t=" + new Date().getTime(); url = url + "?" + query.substring(1); //将服务器返回的JSON数据放到全局变量 window["fwJsonpCallback"+curFwJsonpCallbackId] = function(data){ window.fwJsonpData[""+curFwJsonpCallbackId] = data; }; jsonpScript.src = url; document.getElementsByTagName("head")[0].appendChild(jsonpScript); //截取url的服务器地址部分并返回 function getServerUrl(aurl){ var pos = 0; for(var i=0;i<4;i++){ pos = aurl.indexOf("/", pos+1); } return aurl.substring(0,pos); } } function createCookie(name,value,millis,path,domain,secure) { var expires = ""; if (millis != null) { var date = new Date(); date.setTime(date.getTime()+(millis)); expires = "; expires="+date.toGMTString(); } value = escape(value); document.cookie = name+"="+value+expires+ (( path ) ? "; path=" + path : "" ) + (( domain ) ? "; domain=" + domain : "" ) + (( secure ) ? "; secure" : "" ); } function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return unescape(c.substring(nameEQ.length,c.length)); } return null; }