/assets/javascripts/miniapplet.js
https://github.com/descala/haltr · JavaScript · 1685 lines · 1031 code · 284 blank · 370 comment · 377 complexity · 705d67f8c50fa1d048c0ae1ac1f90302 MD5 · raw file
Large files are truncated click here to view the full file
- if (document.all && !window.setTimeout.isPolyfill) {
- var __nativeST__ = window.setTimeout;
- window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
- var aArgs = Array.prototype.slice.call(arguments, 2);
- return __nativeST__(vCallback instanceof Function ? function () {
- vCallback.apply(null, aArgs);
- } : vCallback, nDelay);
- };
- window.setTimeout.isPolyfill = true;
- }
-
- var MiniApplet = {
-
- VERSION : "1.2",
-
- JAR_NAME : 'miniapplet-full_1_2u1.jar',
-
- JAVA_ARGUMENTS : '-Xms512M -Xmx512M',
-
- CUSTOM_JAVA_ARGUMENTS : null,
-
- clienteFirma : null,
-
- codeBase : null,
-
- storageServletAddress : null,
-
- retrieverServletAddress : null,
-
- clientType : null,
-
- severeTimeDelay : false,
-
- selectedLocale : null,
-
- /* Almacenes de certificados */
-
- KEYSTORE_WINDOWS : "WINDOWS",
-
- KEYSTORE_APPLE : "APPLE",
-
- KEYSTORE_PKCS12 : "PKCS12",
-
- KEYSTORE_PKCS11 : "PKCS11",
-
- KEYSTORE_FIREFOX : "MOZ_UNI",
-
- /* Valores para la configuracion de la comprobacion de tiempo */
-
- CHECKTIME_NO : "CT_NO",
-
- CHECKTIME_RECOMMENDED : "CT_RECOMMENDED",
-
- CHECKTIME_OBLIGATORY : "CT_OBLIGATORY",
-
- /* ------------------------------------------------ */
- /* Constantes para la operacion interna del Cliente */
- /* ------------------------------------------------ */
-
- /* Longitud maximo de una URL en Android para la invocacion de una aplicacion nativa. */
- MAX_LONG_ANDROID_URL : 2000,
-
- /* Longitud maximo de una URL en iOS para la invocacion de una aplicacion nativa. */
- MAX_LONG_IOS_URL : 80000,
-
- /* Longitud maximo de una URL en Windows 8 para la invocacion de una aplicacion nativa. */
- MAX_LONG_WINDOWS8_URL : 2000,
-
- /* Tamano del buffer con el que se pasa informacion al applet */
- BUFFER_SIZE : 1024 * 1024,
-
- /* Cadena que determina el fin de una respuesta */
- EOF : "%%EOF%%",
-
- TYPE_APPLET : "APPLET",
-
- TYPE_JAVASCRIPT : "JAVASCRIPT",
-
- /* ------------------------------------ */
- /* Funciones de comprobacion de entorno */
- /* ------------------------------------ */
-
- /**
- * Determina con un boolean si nuestro cliente es Android
- */
- isAndroid : function () {
- return navigator.userAgent.toUpperCase().indexOf("ANDROID") != -1 ||
- navigator.appVersion.toUpperCase().indexOf("ANDROID") != -1 ||
- // Para la deteccion de los Kindle Fire
- navigator.userAgent.toUpperCase().indexOf("SILK/") != -1 ||
- navigator.userAgent.toUpperCase().indexOf("KFJWI") != -1 ||
- navigator.userAgent.toUpperCase().indexOf("KFJWA") != -1 ||
- navigator.userAgent.toUpperCase().indexOf("KFTT") != -1 ||
- navigator.userAgent.toUpperCase().indexOf("KFOT") != -1 ||
- navigator.userAgent.toUpperCase().indexOf("KINDLE FIRE") != -1
- ;
- },
-
- /**
- * Determina con un boolean si nuestro cliente es iOS.
- */
- isIOS : function () {
- return (navigator.userAgent.toUpperCase().indexOf("IPAD") != -1) ||
- (navigator.userAgent.toUpperCase().indexOf("IPOD") != -1) ||
- (navigator.userAgent.toUpperCase().indexOf("IPHONE") != -1);
- },
-
- /** Comprueba si se permite la ejecucion de ActiveX. */
- isActivexEnabled : function () {
- var supported = null;
- try {
- supported = !!new ActiveXObject("htmlfile");
- } catch (e) {
- supported = false;
- }
-
- return supported;
- },
-
- /** Determina con un boolean si nos encontramos en Windows 8/8.1 */
- isWindows8 : function () {
- return navigator.userAgent.indexOf("Windows NT 6.2") != -1 || /* Windows 8 */
- navigator.userAgent.indexOf("Windows NT 6.3") != -1; /* Windows 8.1 */
- },
-
- /** Determina con un boolean si nos encontramos en Windows RT */
- isWindowsRT : function () {
- return MiniApplet.isWindows8() && navigator.userAgent.indexOf("ARM;") != -1;
- },
-
- /** Determina con un boolean si estamos en Internet Explorer */
- isInternetExplorer : function () {
- return !!(navigator.userAgent.match(/MSIE/)) /* Internet Explorer 10 o inferior */
- || !!(navigator.userAgent.match(/Trident/) && navigator.userAgent.match(/rv:11/)); /* Internet Explorer 11 o superior */
- },
-
- isFirefoxUAM : function () {
- return navigator.userAgent.indexOf("UAM") > 0;
- },
-
- /** Determina con un boolean si nos encontramos en un entorno Windows 8 en modo "Modern UI".
- * Este metodo no es infalible dado que el navegador no ofrece forma de saberlo.
- * La comprobacion . */
- isWindows8ModernUI : function () {
- return MiniApplet.isWindows8() && !MiniApplet.isActivexEnabled() && MiniApplet.isInternetExplorer();
- },
-
- /**
- * Determina con un boolean si se accede a la web con Chrome
- */
- isChrome : function () {
- return navigator.userAgent.toUpperCase().indexOf("CHROME") != -1 ||
- navigator.userAgent.toUpperCase().indexOf("CHROMIUM") != -1;
- },
-
- /**
- * Determina con un boolean si el navegador es Internet Explorer 10
- */
- isIE10 : function () {
- return navigator.userAgent.toUpperCase().indexOf("MSIE 10.0") != -1;
- },
-
- /**
- * Determina con un boolean si el navegador es Internet Explorer 11
- */
- isIE11 : function () {
- return !!navigator.userAgent.match(/Trident.*rv 11\./);
- },
-
- isURLTooLong : function (url) {
- if (MiniApplet.isAndroid()) {
- return url.length > MiniApplet.MAX_LONG_ANDROID_URL;
- }
- else if (MiniApplet.isIOS()) {
- return url.length > MiniApplet.MAX_LONG_IOS_URL;
- }
- else if (MiniApplet.isWindows8()) {
- return url.length > MiniApplet.MAX_LONG_WINDOWS8_URL;
- }
- return false;
- },
-
- /** Indica si el navegador detecta Java. Este valor no es completamente fiable, ya que
- * Internet Explorer siempre indica que si esta activado. */
- isJavaEnabled : function () {
- return navigator.javaEnabled();
- },
-
- /** Permite habilitar la comprobacion de la hora local contra la hora del servidor y
- * establecer un tiempo maximo permitido y el comportamiento si se supera.
- * Parametros:
- * - checkType: Tipo de comprobacion. Admite los valores CT_NO, CT_RECOMMENDED y CT_OBLIGATORY.
- * - maxMillis: Tiempo maximo de desfase en milisegundos.
- * Cuando el HTML es local, no se realiza ningun tipo de comprobacion.
- * */
- checkTime : function (checkType, maxMillis) {
-
- if (checkType == undefined || checkType == null || checkType == MiniApplet.CT_NO
- || maxMillis == undefined || maxMillis == null || maxMillis <= 0) {
- return;
- }
-
- // Hacemos una llamada al servidor para conocer su hora
- var xhr = new XMLHttpRequest();
- xhr.open('GET', document.URL + '/' + Math.random(), false);
- xhr.send();
-
- // Recogemos la hora local, nada mas obtener la respuesta del servidor
- var clientDate = new Date();
-
- // Tomamos la hora a partir de la respuesta del servidor. Si esta es 0, estamos en local
- var serverDate = new Date(xhr.getResponseHeader("Date"));
- if (serverDate == null || serverDate.getTime() == 0) {
- // No hacemos nada si estamos en local
- return;
- }
-
- var delay = Math.abs(clientDate.getTime() - serverDate.getTime());
- if (delay > maxMillis) {
- if (checkType == MiniApplet.CHECKTIME_RECOMMENDED) {
- alert("Se ha detectado un desfase horario entre su sistema y el servidor. Se recomienda que se corrija antes de pulsar Aceptar para continuar." +
- "\nHora de su sistema: " + clientDate.toLocaleString() +
- "\nHora del servidor: " + serverDate.toLocaleString());
- }
- else if (checkType == MiniApplet.CHECKTIME_OBLIGATORY) {
- MiniApplet.severeTimeDelay = true;
- alert("Se ha detectado un desfase horario entre su sistema y el servidor. Debe corregir la hora de su sistema antes de continuar." +
- "\nHora de su sistema: " + clientDate.toLocaleString() +
- "\nHora del servidor: " + serverDate.toLocaleString());
- }
- }
- },
-
- /** Establece los parametros de configuracion para la correcta seleccion del almacen
- * de claves que se debe cargar. */
- configureKeyStore : function () {
- if (MiniApplet.isFirefoxUAM()) {
- if (MiniApplet.CUSTOM_JAVA_ARGUMENTS == null) {
- MiniApplet.CUSTOM_JAVA_ARGUMENTS = "";
- }
- MiniApplet.CUSTOM_JAVA_ARGUMENTS += " -Des.gob.afirma.keystores.mozilla.UseEnvironmentVariables=true";
- }
- },
-
- /** Carga el MiniApplet. */
- cargarMiniApplet : function (base, keystore) {
-
- // Antes que nada, comprobamos que no haya un desfase horario declarado como
- // grave.
- if (MiniApplet.severeTimeDelay) {
- return;
- }
-
- // Si estamos claramente en un sistema movil o que no permite la ejecucion de Java,
- // cargamos directamente el Cliente JavaScript
- if (MiniApplet.isAndroid() || MiniApplet.isIOS() || MiniApplet.isWindowsRT()) {
- MiniApplet.cargarAppAfirma(base);
- return;
- }
-
- // Si estamos en un entorno que permite Java, comprobamos si esta disponible
- // y en caso de no estarlo, tambien cargamos el Cliente JavaScript.
- if (!MiniApplet.isJavaEnabled()) {
- MiniApplet.cargarAppAfirma(base);
- return;
- }
-
- // Configuramos los argumentos para la seleccion de almacen
- MiniApplet.configureKeyStore();
-
- // Incluso si el navegador informa que hay Java, puede no haberlo (Internet Explorer
- // siempre dice que hay), asi que cargamos el applet, pero tenemos en cuenta que en
- // caso de error debemos cargar el cliente JavaScript
- MiniApplet.codeBase = (base != undefined && base != null) ? base : './';
-
- var keystoreConfig = keystore;
- if (keystoreConfig == undefined) {
- keystoreConfig = null;
- }
-
- var attributes = {
- 'id': 'miniApplet',
- 'name': 'MiniApplet @firma (Gobierno de Espa\u00F1a)',
- 'type': 'application/x-java-applet',
- 'width': 1,
- 'height': 1
- };
-
- // Los argumentos de java no llegan al propio applet en las pruebas con Java 6 y 7,
- // asi que (salvo los argumentos de carga) vamos a pasarlos como un parametro mas al
- // applet para luego establecerlos internamente.
- var parameters = {
- 'keystore': keystoreConfig,
- 'userAgent': window.navigator.userAgent,
- 'archive': MiniApplet.codeBase + '/' + MiniApplet.JAR_NAME,
- 'code': 'es.gob.afirma.miniapplet.MiniAfirmaApplet',
- 'java-vm-args': MiniApplet.JAVA_ARGUMENTS,
- 'java_arguments': MiniApplet.JAVA_ARGUMENTS,
- 'custom_java_arguments': MiniApplet.CUSTOM_JAVA_ARGUMENTS,
- 'codebase_lookup': false,
- 'separate_jvm': true,
- 'locale': MiniApplet.selectedLocale
- };
-
- MiniApplet.loadMiniApplet(attributes, parameters);
-
- MiniApplet.clienteFirma = document.getElementById("miniApplet");
-
- // Si no esta definido el cliente es porque se ha intentado cargar el applet
- // y no se ha podido, asi que se usara la aplicacion nativa
- if (MiniApplet.clienteFirma == null) {
- MiniApplet.cargarAppAfirma(MiniApplet.codeBase);
- }
- },
-
- sign : function (dataB64, algorithm, format, params, successCallback, errorCallback) {
-
- this.forceLoad();
- if (MiniApplet.clientType == MiniApplet.TYPE_APPLET) {
- try {
- this.setData(dataB64);
- if (successCallback == undefined || successCallback == null) {
- return this.buildData(MiniApplet.clienteFirma.sign(algorithm, format, params));
- }
- successCallback(this.buildData(MiniApplet.clienteFirma.sign(algorithm, format, params)));
- } catch(e) {
- if (errorCallback == undefined || errorCallback == null) {
- throw e;
- }
- errorCallback(MiniApplet.clienteFirma.getErrorType(), MiniApplet.clienteFirma.getErrorMessage());
- }
- }
- else if (MiniApplet.clientType == MiniApplet.TYPE_JAVASCRIPT) {
- errorCallback('Haltr','Please enable Java')
- // MiniApplet.clienteFirma.sign(dataB64, algorithm, format, params, successCallback, errorCallback);
- }
- },
-
- coSign : function (signB64, dataB64, algorithm, format, params, successCallback, errorCallback) {
-
- this.forceLoad();
- if (MiniApplet.clientType == MiniApplet.TYPE_APPLET) {
- try {
- this.setData(signB64);
- if (successCallback == undefined || successCallback == null) {
- return this.buildData(MiniApplet.clienteFirma.coSign(dataB64, algorithm, format, params));
- }
- successCallback(this.buildData(MiniApplet.clienteFirma.coSign(dataB64, algorithm, format, params)));
- } catch(e) {
- if (errorCallback == undefined || errorCallback == null) {
- throw e;
- }
- errorCallback(MiniApplet.clienteFirma.getErrorType(), MiniApplet.clienteFirma.getErrorMessage());
- }
- }
- else if (MiniApplet.clientType == MiniApplet.TYPE_JAVASCRIPT) {
- MiniApplet.clienteFirma.coSign(signB64, dataB64, algorithm, format, params, successCallback, errorCallback);
- }
- },
-
- counterSign : function (signB64, algorithm, format, params, successCallback, errorCallback) {
-
- this.forceLoad();
- if (MiniApplet.clientType == MiniApplet.TYPE_APPLET) {
- try {
- this.setData(signB64);
- if (successCallback == undefined || successCallback == null) {
- return this.buildData(MiniApplet.clienteFirma.counterSign(algorithm, format, params));
- }
- successCallback(this.buildData(MiniApplet.clienteFirma.counterSign(algorithm, format, params)));
- } catch(e) {
- if (errorCallback == undefined || errorCallback == null) {
- throw e;
- }
- errorCallback(MiniApplet.clienteFirma.getErrorType(), MiniApplet.clienteFirma.getErrorMessage());
- }
- }
- else if (MiniApplet.clientType == MiniApplet.TYPE_JAVASCRIPT) {
- MiniApplet.clienteFirma.counterSign(signB64, algorithm, format, params, successCallback, errorCallback);
- }
- },
-
- getBase64FromText : function (plainText, charset) {
- this.forceLoad();
- return MiniApplet.clienteFirma.getBase64FromText(plainText, charset);
- },
-
- getTextFromBase64 : function (dataB64, charset) {
- this.forceLoad();
- return MiniApplet.clienteFirma.getTextFromBase64(dataB64, charset);
- },
-
- saveDataToFile : function (dataB64, title, fileName, extension, description) {
- this.forceLoad();
- if (MiniApplet.clientType == MiniApplet.TYPE_APPLET) {
- this.setData(dataB64);
- return MiniApplet.clienteFirma.saveDataToFile(title, fileName, extension, description);
- }
- else if (MiniApplet.clientType == MiniApplet.TYPE_JAVASCRIPT) {
- return MiniApplet.clienteFirma.saveDataToFile(dataB64, title, fileName, extension, description);
- }
- return null;
- },
-
- getFileNameContentBase64 : function (title, extensions, description, filePath) {
- this.forceLoad();
- return this.buildData(MiniApplet.clienteFirma.getFileNameContentBase64(title, extensions, description, filePath));
- },
-
- getMultiFileNameContentBase64 : function (title, extensions, description, filePath) {
- this.forceLoad();
- return this.buildData(MiniApplet.clienteFirma.getMultiFileNameContentBase64(title, extensions, description, filePath));
- },
-
- echo : function () {
- this.forceLoad();
- return MiniApplet.clienteFirma.echo();
- },
-
- setStickySignatory : function (sticky) {
- this.forceLoad();
- return MiniApplet.clienteFirma.setStickySignatory(sticky);
- },
-
- setLocale : function (locale) {
- MiniApplet.selectedLocale = locale;
- },
-
- getErrorMessage : function () {
- this.forceLoad();
- return MiniApplet.clienteFirma.getErrorMessage();
- },
-
- getErrorType : function () {
- this.forceLoad();
- return MiniApplet.clienteFirma.getErrorType();
- },
-
- getCurrentLog : function () {
- this.forceLoad();
- return " === JAVASCRIPT INFORMATION === " +
- "\nnavigator.appCodeName: " + navigator.appCodeName +
- "\nnavigator.appName: " + navigator.appName +
- "\nnavigator.appVersion: " + navigator.appVersion +
- "\nnavigator.platform: " + navigator.platform +
- "\nnavigator.userAgent: " + navigator.userAgent+
- "\nnavigator.javaEnabled(): " + navigator.javaEnabled() +
- "\nscreen.width: " + (window.screen ? screen.width : 0) +
- "\nscreen.height: " + (window.screen ? screen.height : 0) +
- "\n\n === CLIENTE LOG === \n" +
- MiniApplet.clienteFirma.getCurrentLog();
- },
-
- setServlets : function (storageServlet, retrieverServlet) {
-
- MiniApplet.storageServletAddress = storageServlet;
- MiniApplet.retrieverServletAddress = retrieverServlet;
-
- if (MiniApplet.clienteFirma && MiniApplet.clienteFirma.setServlets) {
- MiniApplet.clienteFirma.setServlets(storageServlet, retrieverServlet);
- }
- },
-
- /*************************************************************
- * FUNCIONES PARA EL DESPLIEGUE DEL APPLET *
- **************************************************************/
-
- loadMiniApplet : function (attributes, parameters) {
- // Internet Explorer (a excepcion de la version 10) se carga mediante un
- // elemento <object>. El resto con un <embed>.
- if (MiniApplet.isInternetExplorer()) { // && !MiniApplet.isIE10()) {
-
- var appletTag = "<object classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' width='" + attributes["width"] + "' height='" + attributes["height"] + "' id='" + attributes["id"] + "'>";
-
- if (attributes != undefined && attributes != null) {
- for (var attribute in attributes) {
- appletTag += "<param name='" + attribute + "' value='" + attributes[attribute] + "' />";
- }
- }
-
- if (parameters != undefined && parameters != null) {
- for (var parameter in parameters) {
- appletTag += "<param name='" + parameter + "' value='" + parameters[parameter] + "' />";
- }
- }
-
- appletTag += "</object>";
-
- // Al agregar con append() estos nodos no se carga automaticamente el applet en IE10 e inferiores, así que
- // hay que usar document.write() o innerHTML. Para asegurarnos de no pisar HTML previo, crearemos un <div>
- // en la pagina, lo recogeremos e insertaremos dentro suyo el codigo del applet.
- var divElem = document.createElement("div");
- var idAtt = document.createAttribute("id");
- idAtt.value = 'divAfirmaApplet';
- divElem.setAttributeNode(idAtt);
-
- document.body.appendChild(divElem);
-
- document.getElementById("divAfirmaApplet").innerHTML = appletTag;
- }
- else {
- var embed = document.createElement("embed");
-
- if (attributes != undefined && attributes != null) {
- for (var attribute in attributes) {
- var att = document.createAttribute(attribute);
- att.value = attributes[attribute];
- try {
- embed.setAttributeNode(att);
- }
- catch (e) {
- // Probamos este como alternativa en caso de error. Caso detectado en:
- // - IE10 sin modo de compabilidad con el Document Mode de IE7.
- // - Firefox en Mac OS X
- // Este intento no soluciona el error, pero evita que se propague
- embed.setAttribute(attribute, attributes[attribute]);
- }
- }
- }
-
- if (parameters != undefined && parameters != null) {
- for (var parameter in parameters) {
- var att = document.createAttribute(parameter);
- att.value = parameters[parameter];
- embed.setAttributeNode(att);
- }
- }
-
- document.body.appendChild(embed);
- }
- },
-
- /**
- * Establece los datos que debera procesar el applet MiniApplet.
- */
- forceLoad : function () {
-
- // Antes que nada, comprobamos que no haya un desfase horario declarado como
- // grave.
- if (MiniApplet.severeTimeDelay) {
- return;
- }
- if (MiniApplet.clientType == null) {
- MiniApplet.clienteFirma = document.getElementById("miniApplet");
- try {
- MiniApplet.clienteFirma.echo();
- MiniApplet.clientType = MiniApplet.TYPE_APPLET;
- } catch (e) {
- MiniApplet.cargarAppAfirma(MiniApplet.codeBase);
- }
- MiniApplet.setServlets(MiniApplet.storageServletAddress, MiniApplet.retrieverServletAddress);
- }
- },
-
- /**
- * Establece los datos que debera procesar el applet MiniApplet.
- */
- setData : function (dataB64) {
-
- if (dataB64 == null) {
- return;
- }
- else if (dataB64.length <= MiniApplet.BUFFER_SIZE) {
- MiniApplet.clienteFirma.addData(dataB64);
- }
- else {
- MiniApplet.clienteFirma.addData(dataB64.substring(0, MiniApplet.BUFFER_SIZE));
- this.setData(dataB64.substring(MiniApplet.BUFFER_SIZE));
- }
- },
-
- /**
- * Construye el resultado de una funcion a partir de los trozos en la que esta los divide.
- */
- buildData : function (dataB64) {
- var buffer = dataB64;
- var chunk = MiniApplet.clienteFirma.getRemainingData();
- while(chunk != MiniApplet.EOF) {
- buffer += chunk;
- chunk = MiniApplet.clienteFirma.getRemainingData();
- }
- return buffer;
- },
-
- /**************************************************************
- **************************************************************
- **************************************************************
- **************************************************************
- * FUNCIONES DEL CLIENTE JAVASCRIPT *
- **************************************************************
- **************************************************************
- **************************************************************
- **************************************************************/
-
- /**
- * Establece el objeto que simula ser el Applet de firma en sistemas en los que no se
- * soportan los applets.
- */
- cargarAppAfirma : function (clientAddress) {
- document.miniapplet = new MiniApplet.AppAfirmaJS(clientAddress);
- MiniApplet.clienteFirma = document.miniapplet;
-
- MiniApplet.clientType = MiniApplet.TYPE_JAVASCRIPT;
- },
-
-
- /**
- * Objeto JavaScript que va a reemplazar al cliente de firma en los entornos en los que
- * no pueden ejecutarse applets.
- */
- AppAfirmaJS : function (clientAddress) {
-
- var UnsupportedOperationException = "java.lang.UnsupportedOperationException";
-
- /**
- * Atributos para la configuracion del objeto sustituto del applet Java de firma
- */
- this.errorMessage = '';
- this.errorType = '';
-
- if (clientAddress.indexOf("://") != -1 && clientAddress.indexOf("/", clientAddress.indexOf("://") + 3) != -1) {
- var servletsBase = clientAddress.substring(0, clientAddress.indexOf("/", clientAddress.indexOf("://") + 3));
- this.retrieverServletAddress = servletsBase + "/SignatureRetrieverServer/RetrieveService";
- this.storageServletAddress = servletsBase + "/SignatureStorageServer/StorageService";
- } else {
- this.retrieverServletAddress = clientAddress + "/SignatureRetrieverServer/RetrieveService";
- this.storageServletAddress = clientAddress + "/SignatureStorageServer/StorageService";
- }
-
- /**
- * Inicia el proceso de firma electronica.
- * Implementada en el applet Java de firma
- */
- this.sign = function(dataB64, algorithm, format, extraParams, successCallback, errorCallback) {
- this.signOperation("sign", dataB64, algorithm, format, extraParams, successCallback, errorCallback);
- };
-
- /**
- * Inicia el proceso de cofirma de una firma electrónica.
- * Implementada en el applet Java de firma.
- */
- this.coSign = function(signB64, dataB64, algorithm, format, extraParams, successCallback, errorCallback) {
- this.signOperation("cosign", signB64, algorithm, format, extraParams, successCallback, errorCallback);
- };
-
- /**
- * Inicia el proceso de contrafirma de una firma electrónica.
- * Implementada en el applet Java de firma.
- */
- this.counterSign = function(signB64, algorithm, format, extraParams, successCallback, errorCallback) {
- this.signOperation("countersign", signB64, algorithm, format, extraParams, successCallback, errorCallback);
- };
-
- /**
- * Realiza una operacion de firma/multifirma.
- * @param signId Identificador de la operacion a realizar (sign, cosign y countersign).
- * @param dataB64 Datos o firma en base 64.
- * @param algorithm Algoritmo de firma.
- * @param format Formato de firma.
- * @param extraParams Parámetros para la configuración de la operación.
- * @param successCallback Método a ejecutar en caso de éxito.
- * @param errorCallback Método a ejecutar en caso de error.
- */
- this.signOperation = function(signId, dataB64, algorithm, format, extraParams, successCallback, errorCallback) {
-
- if (dataB64 == undefined || dataB64 == "") {
- dataB64 = null;
- }
-
- if (dataB64 != null) {
- dataB64 = dataB64.replace(/\+/g, "-").replace(/\//g, "_");
- }
-
- if (isPolicyConfigurated(extraParams)) {
- extraParams = expandPolicy(format, extraParams);
- }
-
- var idSession = generateNewIdSession();
- var cipherKey = generateCipherKey();
-
- var i = 0;
- var params = new Array();
- if (signId != null && signId != undefined) { params[i++] = {key:"op", value:encodeURIComponent(signId)}; }
- if (idSession != null && idSession != undefined) { params[i++] = {key:"id", value:encodeURIComponent(idSession)}; }
- if (cipherKey != null && cipherKey != undefined) { params[i++] = {key:"key", value:encodeURIComponent(cipherKey)}; }
- if (this.storageServletAddress != null && this.storageServletAddress != undefined) { params[i++] = {key:"stservlet", value:this.storageServletAddress}; }
- if (format != null && format != undefined) { params[i++] = {key:"format", value:encodeURIComponent(format)}; }
- if (algorithm != null && algorithm != undefined) { params[i++] = {key:"algorithm", value:encodeURIComponent(algorithm)}; }
- if (extraParams != null && extraParams != undefined) { params[i++] = {key:"properties", value:encodeURIComponent(Base64.encode(extraParams))}; }
- if (MiniApplet.isWindows8()) { params[i++] = {key:"metro", value:MiniApplet.isWindows8ModernUI() ? "true" : "false"}; }
- if (dataB64 != null) { params[i++] = {key:"dat", value:encodeURIComponent(dataB64)}; }
-
- var url = this.buildUrl(signId, params);
-
- // Si la URL es muy larga, realizamos un preproceso para que los datos se suban al
- // servidor y la aplicacion nativa los descargue, en lugar de pasarlos directamente
- if (MiniApplet.isURLTooLong(url)) {
- if (this.storageServletAddress == null || this.storageServletAddress == undefined) {
- throwException("java.lang.IllegalArgumentException", "No se ha indicado la direccion del servlet para el guardado de datos");
- return;
- }
-
- var fileId = this.preProccessData(cipherKey, this.storageServletAddress, signId, params);
- if (!fileId) {
- throwException("java.net.UnknownHostException", "No se han podido enviar los datos a la aplicacion de firma");
- return;
- }
-
- url = this.buildUrlWithoutData(signId, fileId, this.retrieverServletAddress, cipherKey);
- if (MiniApplet.isURLTooLong(url)) {
- throwException("java.lang.IllegalArgumentException", "La URL de invocacion al servicio de firma es demasiado larga.");
- return;
- }
- }
-
- this.execAppIntent(url, idSession, cipherKey, successCallback, errorCallback);
- };
-
- /**
- * Convierte texto plano en texto base 64.
- * Implementada en el applet Java de firma.
- */
- this.getBase64FromText = function(plainText, charset) {
- return Base64.encode(plainText);
- };
-
- /**
- * Convierte texto base 64 en texto plano.
- * Implementada en el applet Java de firma.
- */
- this.getTextFromBase64 = function(base64Text, charset) {
- return Base64.decode(base64Text);
- };
-
- /**
- * Guardado de datos en disco. Se realiza mediante la invocacion de una app nativa.
- */
- this.saveDataToFile = function(dataB64, title, filename, extension, description) {
-
- if (dataB64 != undefined && dataB64 != null && dataB64 != "") {
- dataB64 = dataB64.replace(/\+/g, "-").replace(/\//g, "_");
- }
-
- var idSession = generateNewIdSession();
- var cipherKey = generateCipherKey();
-
- var i = 0;
- var params = new Array();
- params[i++] = {key:"op", value:"save"};
- if (idSession != null && idSession != undefined) { params[i++] = {key:"id", value:encodeURIComponent(idSession)}; }
- if (cipherKey != null && cipherKey != undefined) { params[i++] = {key:"key", value:encodeURIComponent(cipherKey)}; }
- if (this.storageServletAddress != null && this.storageServletAddress != undefined) { params[i++] = {key:"stservlet", value:this.storageServletAddress}; }
- if (title != null && title != undefined) { params[i++] = {key:"title", value:encodeURIComponent(title)}; }
- if (filename != null && filename != undefined) { params[i++] = {key:"filename", value:encodeURIComponent(filename)}; }
- if (extension != null && extension != undefined) { params[i++] = {key:"extension", value:encodeURIComponent(extension)}; }
- if (description != null && description != undefined) { params[i++] = {key:"description", value:encodeURIComponent(description)}; }
- if (MiniApplet.isWindows8()) { params[i++] = {key:"metro", value:MiniApplet.isWindows8ModernUI() ? "true" : "false"}; }
- if (dataB64 != null && dataB64 != undefined && dataB64 != "") { params[i++] = {key:"dat", value:encodeURIComponent(dataB64)}; }
-
- var url = this.buildUrl("save", params);
-
- // Si la URL es muy larga, realizamos un preproceso para que los datos se suban al
- // servidor y la aplicacion nativa los descargue, en lugar de pasarlos directamente
- if (MiniApplet.isURLTooLong(url)) {
- if (this.storageServletAddress == null || this.storageServletAddress == undefined) {
- throwException("java.lang.IllegalArgumentException", "No se ha indicado la direccion del servlet para el guardado de datos");
- return;
- }
-
- var fileId = this.preProccessData(cipherKey, this.storageServletAddress, "save", params);
- if (!fileId) {
- throwException("java.net.UnknownHostException", "No se han podido enviar los datos a la aplicacion de firma");
- return;
- }
-
- url = this.buildUrlWithoutData("save", fileId, this.retrieverServletAddress, cipherKey);
- if (MiniApplet.isURLTooLong(url)) {
- throwException("java.lang.IllegalArgumentException", "La URL de invocacion al servicio de firma es demasiado larga. No se soportan tantas propiedades de configuracion.");
- return;
- }
- }
-
- this.execAppIntent(url, idSession, cipherKey);
- };
-
- /**
- * Carga de un fichero. Operacion no soportada.
- * Implementada en el applet Java de firma.
- */
- this.getFileNameContentBase64 = function(title, extensions, description) {
- this.throwException(UnsupportedOperationException, "La operacion de carga de ficheros no esta soportada");
- };
-
- /**
- * Carga de multiples ficheros. Operacion no soportada.
- * Implementada en el applet Java de firma.
- */
- this.getMultiFileNameContentBase64 = function(title, extensions, description) {
- this.throwException(UnsupportedOperationException, "La operacion de carga de multiples ficheros no esta soportada");
- };
-
- /**
- * Funcion para la comprobacion de existencia del objeto. No hace nada.
- * Implementada en el applet Java de firma.
- */
- this.echo = function() {
- return "Cliente JavaScript";
- };
-
- /**
- * No hace nada.
- * Implementada en el applet Java de firma.
- */
- this.setStickySignatory = function(sticky) {
- // No hace nada
- };
-
- /**
- * Recupera el mensaje de error asociado al ultimo error capturado.
- * Implementada en el applet Java de firma.
- */
- this.getErrorMessage = function() {
- return this.errorMessage;
- };
-
- /**
- * Recupera el tipo del ultimo error capturado.
- * Implementada en el applet Java de firma.
- */
- this.getErrorType = function() {
- return this.errorType;
- };
-
- /**
- * Recupera el log de la aplicacion. Actualmente, el log solo esta
- * disponible en el applet, no en las aplicacion moviles.
- */
- this.getCurrentLog = function() {
- return "Applet no cargado";
- };
-
- /**
- * Funcion para identificar el tipo de objeto del Cliente (javascript, applet,...).
- */
- this.getType = function() {
- return "javascript";
- };
-
- /**
- * Establece las rutas de los servlets encargados de almacenar y recuperar las firmas de los dispositivos moviles.
- */
- this.setServlets = function(storageServlet, retrieverServlet) {
- this.storageServletAddress = storageServlet;
- this.retrieverServletAddress = retrieverServlet;
- };
-
- /**
- * Establece el error indicado como error interno y lanza una excepcion.
- */
- this.throwException = function(type, message) {
- this.errorType = type;
- this.errorMessage = message;
- throw new Exception();
- };
-
- // Constants
- var MAX_NUMBER = 2147483648;
-
- // Pure javascript functions
- function zeroFill(number, width) {
- width -= number.toString().length;
- if (width > 0) {
- return new Array(width + (/\./.test(number) ? 2 : 1)).join('0')
- + number;
- }
- return number + ""; // Always return a string
- }
-
-
- /**
- * Funciones auxiliares del objeto JS del cliente de firma.
- **/
- function generateNewIdSession() {
- return zeroFill(Math.floor((Math.random() * MAX_NUMBER) + 1), 12);
- }
-
- var EXPAND_POLICIY_KEY_AND_VALUE = "expPolicy=FirmaAGE";
-
- /**
- * Identifica si debe expandirse la propiedad de politica de firma.
- * @param config Configuracion de la firma.
- * @returns Indica con true si debe expandirse el parametro de politica, false en caso contrario.
- */
- function isPolicyConfigurated(config) {
- return (config != undefined && config != null) ?
- config.indexOf(EXPAND_POLICIY_KEY_AND_VALUE) > -1 : false;
- }
-
- /**
- * Expande la variable de firma politica de firma si la encuentra en los extra params.
- **/
- function expandPolicy(format, config) {
- var expandedPolicy = "";
- if (compareFormats(format, "CAdES")) {
- expandedPolicy = "policyIdentifier=urn:oid:2.16.724.1.3.1.1.2.1.8\n" +
- "policyQualifier=http://administracionelectronica.gob.es/es/ctt/politicafirma/politica_firma_AGE_v1_8.pdf\n" +
- "policyIdentifierHashAlgorithm=http://www.w3.org/2000/09/xmldsig#sha1\n" +
- "policyIdentifierHash=7SxX3erFuH31TvAw9LZ70N7p1vA=";
- }
- else if (compareFormats(format, "XAdES")) {
- expandedPolicy = "policyIdentifier=urn:oid:2.16.724.1.3.1.1.2.1.8\n" +
- "policyQualifier=http://administracionelectronica.gob.es/es/ctt/politicafirma/politica_firma_AGE_v1_8.pdf\n" +
- "policyIdentifierHashAlgorithm=http://www.w3.org/2000/09/xmldsig#sha1\n" +
- "policyIdentifierHash=V8lVVNGDCPen6VELRD1Ja8HARFk=";
- }
- // else if (compareFormats(format, "PAdES") || compareFormats(format, "PDF")) {
- // // NO DISPONIBLE HASTA LA VERSION 1.9 DE LA POLITICA
- // expandedPolicy = "policyIdentifier=urn:oid:2.16.724.1.3.1.1.2.1.8\n" +
- // "policyQualifier=http://administracionelectronica.gob.es/es/ctt/politicafirma/politica_firma_AGE_v1_8.pdf\n" +
- // "policyIdentifierHashAlgorithm=http://www.w3.org/2000/09/xmldsig#sha1\n" +
- // "policyIdentifierHash=7SxX3erFuH31TvAw9LZ70N7p1vA=";
- // }
-
- if (expandedPolicy != "") {
- config = config.replace(EXPAND_POLICIY_KEY_AND_VALUE, expandedPolicy);
- }
- return config;
- }
-
- /**
- * Compara que un nombre de formato sea equivalente a un formato de firma monofasico.
- * Por ejemplo, que XAdEStri sea igual a XAdES.
- **/
- function compareFormats(format, supportedFormat) {
- format = format.toUpperCase();
- supportedFormat = supportedFormat.toUpperCase();
- return format == supportedFormat ||
- (format.length > supportedFormat.length &&
- format.substr(0, supportedFormat.length) == supportedFormat);
- }
-
- /**
- * Invoca un Intent con la operacion seleccionada, la configuraci\u00F3n establecida y las campos del
- * formulario pasado como parametro. Si se define un callback para tratar el caso de exito o error de
- * la operacion, se intentara descargar el resultado devuelto por la app del servidor intermedio de
- * comunicacion.
- *
- * intentURL: URL para la invocacion del Cliente JavaScript
- * idSession: Identificador de la sesi\u00F3n para la recuperaci\u00F3n del resultado.
- * cipherKey: Clave de cifrado para la respuesta del servidor.
- * successCallback: Actuaci\u00F3n a realizar cuando se recupera el resultado de la operación.
- * errorCallback: Actuaci\u00F3n a realizar cuando ocurre un error al recuperar el resultado.
- */
- this.execAppIntent = function (intentURL, idSession, cipherKey, successCallback, errorCallback) {
-
- // Invocamos al cliente de firma movil.
- this.openUrl(intentURL);
-
- if (successCallback != null || errorCallback != null) {
- if (idSession != null && idSession != undefined &&
- ((successCallback != undefined && successCallback != null) ||
- (errorCallback != undefined && errorCallback != null))) {
- this.getStoredFileFromServlet(idSession, this.retrieverServletAddress, cipherKey, successCallback, errorCallback);
- }
- }
- };
-
- /**
- * Construye una URL para la invocación del Cliente @firma nativo.
- *
- * op: Funcion a invocar en el cliente nativo.
- * params: Par\u00E1metros para la configuraci\u00F3n de la operaci\u00F3n.
- */
- this.buildUrl = function(op, params) {
-
- // Operacion seleccionada
- var intentURL = this.getProtocol() + '://' + op + '?';
- if (params != null && params != undefined) {
- for (var i = 0; i < params.length; i++) {
- intentURL += (i != 0 ? '&' : '') + params[i].key + '=' + params[i].value;
- }
- }
-
- return intentURL;
- };
-
- this.getProtocol = function () {
- // En Windows 8, siempre usaremos el modo "afirmametro", ya que por ahora
- // la aplicacion con el protocolo "afirma" no hay otro disponible
- if (MiniApplet.isWindows8()) {
- return "afirmametro";
- }
- return "afirma";
- };
-
- /**
- * Generan un XML con los datos de configuracion de la operacion indicada,
- * los cifra y lo envia a un servidor para su descarga.
- * @param cipherKey Clave de cifrado. Si no se indica, no se cifra.
- * @param storageServletAddress URL del servlet que almacena.
- * @param op Operacion que se configura.
- * @param params Parametros de configuracion de la operacion
- * @returns El identificador con el que se ha guardado el fichero en servidor o false
- * si se produjo algun error.
- */
- this.preProccessData = function (cipherKey, storageServletAddress, op, params) {
-
- // Identificador del fichero (equivalente a un id de sesion) del que deben recuperarse los datos
- var fileId = generateNewIdSession();
-
- var httpRequest = getHttpRequest();
- if (!httpRequest) {
- this.throwException("java.lang.Exception", "Su navegador no permite preprocesar los datos que desea tratar");
- }
-
- var cipheredDataB64 = cipher(buildXML(op, params), cipherKey);
-
- httpRequest.open("POST", storageServletAddress, false);
- httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
- try {
- httpRequest.send("op=put&v=1_0&id=" + fileId + "&dat=" + cipheredDataB64);
- }
- catch(e) {
- this.errorMessage = "No se pudo conectar con el servidor remoto";
- this.errorType = "java.io.IOException";
- }
-
- if (httpRequest.readyState==4 && httpRequest.status==200) {
- return fileId;
- }
-
- return false;
- };
-
- /**
- * Construye un XML con lo valores del array de parametros proporcionado.
- * @param op Operacion que configuramos
- * @param params Array con los parametros del array.
- * @returns XML.
- */
- function buildXML (op, params) {
- op = (op == null ? "op" : op);
- var xml = '<' + op +'>';
- for (var i = 0; i < params.length; i++) {
- xml += '<e k="' + params[i].key + '" v="' + params[i].value + '"/>';
- }
- return Base64.encode(xml + '</' + op + '>');
- };
-
- /**
- * Crea una URL a partir de los parametros introducidos para la invocación de
- * una app nativa para que descargue la configuracion de la operación a realizar.
- * @param op Codigo de la operacion a la que tiene que invocar la URL.
- * @param id Identificador para la descarga.
- * @param rtServlet Servlet para la descarga de la configuración.
- * @param cipherKey Clave para el descifrado.
- * @returns URL para la llamada a la app con los datos necesarios para que descargue
- * la configuración de la operación a realizar.
- */
- this.buildUrlWithoutData = function (op, id, rtServlet, cipherKey) {
- var j = 0;
- var newParams = new Array();
- newParams[j++] = {key:"fileid", value:id};
- if (rtServlet != null || rtServlet != undefined) {
- newParams[j++] = {key:"rtservlet", value:rtServlet};
- }
- if (cipherKey != null || cipherKey != undefined) {
- newParams[j++] = {key:"key", value:cipherKey};
- }
- return this.buildUrl(op, newParams);
- };
-
- /**
- * Llama a la aplicacion de firma a traves de la URL de invocacion sin que afecte
- * a la pagina que se esta mostrando.
- * @param url URL de invocacion.
- */
- this.openUrl = function (url) {
-
- // Usamos document.location porque tiene mejor soporte por los navegadores que
- // window.location que es el mecanismo estandar
- if (MiniApplet.isChrome()) {
- document.location = url;
- }
- else {
- var iframeElem = document.createElement("iframe");
-
- var srcAttr = document.createAttribute("src");
- srcAttr.value = url;
- iframeElem.setAttributeNode(srcAttr);
-
- var heightAttr = document.createAttribute("height");
- heightAttr.value = 1;
- iframeElem.setAttributeNode(heightAttr);
-
- var widthAttr = document.createAttribute("width");
- widthAttr.value = 1;
- iframeElem.setAttributeNode(widthAttr);
-
- var seamlessAttr = document.createAttribute("seamless");
- seamlessAttr.value = "seamless";
- iframeElem.setAttributeNode(seamlessAttr);
-
- document.body.appendChild(iframeElem);
- }
- };
-
- var iterations = 0;
-
- /**
- * Ejecuta el metodo de error si el html recuperado es tal o el metodo de exito si no lo es,
- * en cuyo caso previamente descifrara el resultado.
- * @param html Resultado obtenido.
- * @param cipherKey Clave para el descifrado del resultado si no es un error.
- * @param successCallback Metodo a ejecutar en caso de exito.
- * @param errorCallback Metodo a ejecutar en caso de error.
- * @returns Devuelve true si se ha fallado pero se puede volver a reintentar, false en caso de
- * error determinante o exito.
- */
- this.successResponseFunction = function(html, cipherKey, successCallback, errorCallback) {
-
- // Si se obtiene el mensaje de error de que el identificador no existe, seguimos intentandolo
- if (html.substr(0, 6).toLowerCase() == "err-06") {
- return true;
- }
-
- // Si se obtiene otro mensaje de error, se deja de intentar y se ejecuta la funcion callback de error
- if (html.substr(0, 4).toLowerCase() == "err-" && html.indexOf(":=") != -1) {
- this.errorMessage = html.substring(html.indexOf(":=") + 2);
- this.errorType = "java.lang.Exception";
- errorCallback(this.errorType, this.errorMessage);
- return false;
- }
-
- // Si no se obtuvo un error y se definio una clave de cifrado privada, desciframos.
- // Los datos cifrados van precedidos por la cantidad de caracteres agregados manualmente al final para
- // cumplir con los requisitos de padding del algoritmo de cifrado. Este numero se separa de la cadena
- // cifrada con el caracter '.'. Devuelve el resultado del descifrado en Base64.
- if (cipherKey != undefined && cipherKey != null) {
- html = decipher(html, cipherKey);
- }
-
- // Ejecutamos la funcion callback de exito y notificamos que se dejen de realizar peticiones
- successCallback(html);
-
- return false;
- };
-
- this.errorResponseFunction = function(type, message, errorCallback) {
-
- this.errorType = (type != null && type.length > 0) ?
- type : "java.lang.Exception";
- this.errorMessage = (message != null && message.length > 0) ?
- message : "No se ha podido extablecer la comunicaci\u00F3n entre la aplicaci\u00F3n de firma y la p\u00E1gina web";
- errorCallback(this.errorType, this.errorMessage);
- };
-
-
- this.getStoredFileFromServlet = function (idDocument, servletAddress, cipherKey, successCallback, errorCallback) {
-
- var httpRequest = getHttpRequest();
- if (!httpRequest) {
- this.throwException("java.lang.Exception", "Su navegador no permite obtener el resulado de la operaci\u00F3n");
- }
-
- iterations = 0;
- setTimeout(retrieveRequest, 4000, httpRequest, servletAddress, "op=get&v=1_0&id=" + idDocument + "&it=0", cipherKey, successCallback, errorCallback);
- };
-
- var NUM_MAX_ITERATIONS = 15;
-
- function retrieveRequest(httpRequest, url, params, cipherKey, successCallback, errorCallback) {
-
- // Contamos la nueva llamada al servidor
- if (iterations > NUM_MAX_ITERATIONS) {
- MiniApplet.clienteFirma.errorResponseFunction("java.util.concurrent.TimeoutException", "El tiempo para la recepcion de la firma por la pagina web ha expirado", errorCallback);
- return;
- }
- iterations++;
-
- //TODO: Separar parametros
- httpRequest.open("POST", url, false);
- httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
-
- try {
- httpRequest.send(params);
- }
- catch(e) {
- // Error en la llamada para al recuperacion del resultado. No lo encuentra o problema
- // de tipo cross-domain
- MiniApplet.clienteFirma.errorResponseFunction("java.lang.IOException", "Ocurrio un error de red en la llamada al servicio de firma", errorCallback);
- return;
- }
-
- if (httpRequest.readyState==4) {
- if (httpRequest.status==200) {
- var needContinue = MiniApplet.clienteFirma.successResponseFunction(httpRequest.responseText, cipherKey, successCallback, errorCallback);
- if (!needContinue) {
- return;
- }
- }
- else {
- MiniApplet.clienteFirma.errorResponseFunction(null, httpRequest.responseText, errorCallback);
- return;
- }
- }
-
- setTimeout(retrieveRequest, 4000, httpRequest, url, params.replace("&it=" + (iterations-1), "&it=" + iterations), cipherKey, successCallback, errorCallback);
- }
-
- // getHttpRequest
- function getHttpRequest() {
- var activexmodes=["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]; //activeX versions to check for in IE
- if (window.ActiveXObject){ //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
- for (var i=0; i<activexmodes.length; i++) {
- try {
- return new ActiveXObject(activexmodes[i]);
- }
- catch(e) {
- //suppress error
- }
- }
- }
- else if (window.XMLHttpRequest) { // if Mozilla, Safari etc
- return new XMLHttpRequest();
- }
- else {
- return false;
- }
- }
-
- /**
- * Genera un numero aleatorio para utilizar como clave de cifrado.
- */
- function generateCipherKey() {
- return zeroFill(Math.floor(((Math.random() * MAX_NUMBER) + 1) % 100000000), 8);
- }
-
- /**
- * Realiza un descifrado DES compatible con Java (Algoritmo DES, modo CBC, sin Padding).
- * Recibe en base 64 la cadena de texto cifrado antecedido por el padding anadido manualmente
- * a los datos para permitir el cifrado DES (separado por un punto ('.')), ademas de la clave
- * para descifrar.
- * Como resultado devuelve la cadena de texto descifrada en base 64.
- */
- function decipher(cipheredData, key) {
-
- var dotPos = cipheredData.indexOf('.');
- var padding = cipheredData.substr(0, dotPos);
-
- var deciphered = des(key, base64ToString(cipheredData.substr(dotPos + 1).replace(/\-/g, "+").replace(/\_/g, "/")), 0, 0, null);
-
- return stringToBase64(deciphered.substr(0, deciphered.length - padding - 8));
- }
-
- /**
- * Realiza un cifrado DES compatible con Java (Algoritmo DES, modo CBC, sin Padding).
- * @param dataB64 Cadena de texto base 64.
- * @param key Clave de cifrado.
- * @return Base 64 cifrado.
- */
- function cipher(dataB64, key) {
-
- var data = base64ToString(dataB64.replace(/\-/g, "+").replace(/\_/g, "/"));
- var padding = (8 - (data.length % 8)) % 8;
-
- // Los datos cifrados los pasamos a base 64 y, antes de devolverlos le anteponemos el padding que
- // le habra agregado el metodo de cifrado separados por un punto ('.').
- return padding + "." + stringToBase64(des(key, data, 1, 0, null)).replace(/\+/g, "-").replace(/\//g, "_");
- }
- }
- };
-
-
-
-
-
- /**
- * Base64 encode / decode
- * http://www.webtoolkit.info/
- */
- var Base64 = {
-
- // private property
- _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
- _keyStr_URL_SAFE : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",
-
- // public method for encoding
- encode : function (input, URL_SAFE) {
-
- var keyStr = (URL_SAFE == true) ? this._keyStr_URL_SAFE : this._keyStr;
-
- var output = "";
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;…