Crear un archivo robots.txt

Como sabréis, los motores de búsqueda se sirven de «robots», programas que indexan las páginas web alojadas en un servidor, para que estas puedan ser localizadas por el buscador (Google, yahoo…). Por defecto todos los robots tendrán el acceso permitido y podrán ver todo lo que tengamos alojado en la raíz de nuestro servidor, y en muchos casos eso no nos interesa.

¿Cómo arreglamos esto? Con el robots.txt, archivo que generalmente guardaremos en la raíz de nuestro servidor. En él podemos incluir qué directorios queremos desactivar y para qué bots. Un ejemplo simple: este robots.txt bloquería todo el directorio raíz (con todos sus subdirectorios) para todos los bots:

User-agent: *
Disallow: /
#y si quieres poner comentarios, que no serán interpretados por los bots/crawler basta con comenzar la línea con este carater#

Las utilidades del robots.txt pueden ser más de las que a priori imaginas. Obviamente evita que se indexe contenido que quieras mantener oculto o protegido, pero también te permite evitar que se indexe contenido duplicado (recuerda, el contenido duplicado rebaja tu page-rank), impedir la idexación de bots no deseados (no todos los bots son de buscadores legítimos) y si tienes un site con mucho tráfico evitará una carga de trabajo extra sobre el servidor.

Vamos a ir por partes, explicando algunas peculiaridades.

La primera es que puedes incluir varios Disallow bajo un mismo user agent, pero no varios user agent encima de un disallow.

#así sí
User-agent: bingbot
Disallow: /wp-content/
Disallow: /js/

User-agent: Googlebot
Disallow: /wp-content/
Disallow: /js/

#así NOOOOOOO
User-agent: bingbot
User-agent: Googlebot
Disallow: /wp-content/
Disallow: /js/

En cuanto al uso de comodines y expresiones regulares… puedes usarlos específicamente para
Googlebot y Slurp (el bot de Yahoo). Por lo que he leído el resto no las aceptan, así que no lo intentes usar de forma general ya que muchos crawlers no lo entenderán y sí indizarán esa página.

#esto bloquería todos los archivos .js para Slurp
User-agent: Slurp
Disallow: /*.js?

#esto lo bloquería para Slurp y Googlebot, pero el resto no lo entenderían e indizarían
User-agent: *
Disallow: /*.js?

Si tienes un sitemap en el servidor puedes incluirlo en el robots.txt con una simple línea:

Sitemap: http://miservidor/sitemap.xml

Y, como te decía arriba, también puedes reducir la frecuencia de rastreo para que los bots no estén entrando todo el día. Si tienes una web con muchas visitas pero pocas actualizaciones basta con especificarlo con Crawl-delay. Eso sí, no todos los bots lo soportan:

#así le dirías al robot de Bing que sólo entre cada 45 días
User-agent: bingbot
Crawl-delay:45

También se puede usar la palabra Allow en lugar de Disallow… pero por defecto todos los directorios y archivos están permitidos y, además, no todos los bots lo van a entender. Así que mejor Disallow para restringir zonas que Allow para habilitarlas.

Recuperar una contraseña perdida en Ubuntu

Me pasó ayer que a una amiga mía le dejaron un equipo con Ubuntu 12.10 instalado y quería que le ayudara con algunas cosillas. Era la primera vez que usaba un sistema Linux. Si recordáis vuestra «primera vez» os imagináis que estaría llena de dudas (yo estaba lleno de dudas, y eso que llegué a Linux mayor y curtido, después de haber bregado en MS-DOS y con el BASIC de Amstrad en mis inicios informáticos) así que fui para echarle un ojo al equipo e intentar aclararle las preguntas que pudiera tener. Y claro, el primer problema que me encuentro es que el le dejó el equipo le dijo la contraseña, pero no se la escribió… eran varios caracteres pero por cuestiones fonéticas y de mayúsculas/minúsculas y espacios teníamos como… no sé, un huevo y medio de combinaciones. Conclusión, acabo antes cambiando la contraseña que intentando sacar esa por fuerza bruta.

Lo primero para recuperar la contraseña es arrancar en el modo recovery. Para hacer esto tienes que arrancar el equipo y después de que cargue la BIOS, y antes de que aparezca el logo de Ubuntu, pulsáis SHIFT para entrar a GRUB. Allí váis a la línea «Advanced Options» y tras ello seleccionáis la línea que acaba con (recovery mode).Y finalmente elegís la opción Drop to root shell prompt.

Bueno, ya estáis en una consola con permisos de root. Ahora os toca «montar» la partición / para poder escribir en ella:

mount -o remount,rw /
#y si tienes otras particiones las puedes montar con
mount --all

Muy bien, con la partición montada ya puedes escribir en el disco, ahora sólo te queda escribir

passwd nombre_de_usuario

Tras esto te pedirá que escribas dos veces la nueva contraseña (dos veces para confirmar que la escribes bien, por seguridad). Ahora sólo te queda apagar o reiniciar. Tienes varias opciones que pueden ser las siguientes:

#reiniciar
init 6
#apagar
init 0
#apagar (otra forma)
shutdown -r now
#reiniciar (otra forma)
reboot

Y contraseña perdida reseteada.

Recursos gratuitos para programación web y móvil

Vamos con una minientrada con algunas páginas con recursos totalmente de gratis para vuestros desarrollos (La entrada es de 2013, pero a octubre de 2019 la he recordado y he decidido actualizarla quitando algunos enlaces que ya no funcionan y añadiendo alguna más):

  • HTML5 UP!: Una web, del creador de la anterior, que nos ofrece una, de momento, pequeña colección de plantillas responsivas en HTML5 y CSS3. Como la anterior, totalmente gratis.
  • Web Resources Depot: En este caso se trata de un blog que recoge a diario diversos recursos gratuitos publicados en distitnas páginas.
  • Webappers:Similar a Web Resources Depot, una web que publica a diario recursos publicados en otras páginas.
  • Google Fonts: Si andas buscando tipografías que además no te den problemas de compatibilidad entre navegadores, este servicio de Google (de momento gratuito) te puede solucionar la papeleta. Dispone de momento de más de 200 tipografías para tu uso y disfrute.
  • Font Squirrel: Por no dar todo el poder a Google, otra alternativa puede ser Font Squirrel, otra página de tipografías gratuitas para tu web.
  • Easel.ly: Esta página nos permite crear infografías on-line de manera sencilla y exportarlas a .jpg, con multitud de plantillas.
  • Online OCR: Hay clientes muy zotes, todos los sabemos. Algunos te envían los textos escaneados en un pdf del que no puedes copiar ni pegar (¿lo imprimieron y escaneron?). Esta web te soluciona la papeleta devolviéndote el resultado en múltiples formatos. Tiene limitaciones en su plan gratuito, pero permite trabajar bastante.
  • Bounce: ¿Quieres hacer una captura de una página completa y añadirle notas por encima de manera fácil? Esta herramienta te lo permite. Seleccionas una url, la carga… y listo.
  • Pexels: Sitio web con fotografías gratuitas del que hablamos en un artículo previo.
  • Unsplash: Sitio web con fotografías gratuitas del que ya hablamos en un artículo previo.
  • Freebiesbug: Plantillas, iconos y otros recursos web.

Una serie de utilidades para dar un toque más elegante y funcional a tus webs.

Listas con imágenes en jQueryMobile

Vamos con una entrada sobre jQueryMobile, que hace que no le damos a la Mobile Web (sigo a la espera de que empiece el curso de Audacity, al que me apunté ya en agosto…). Ya hablamos de cómo hacer listas, desde luego, pero ¿cómo hacer listas con un pequeño thumbnail a la izquierda? Es muy simple, de hecho.

Como siempre empiezas descargando jQuery y jQueryMobile y añadiéndolos a tu código. Luego en el código metes una lista aplicándole un par de clases… pero eso mejor lo vemos con ejemplos de código. En este primer ejemplo veremos una lista donde cada elemento es un enlace, con una foto en la izquierda y un texto grande:

<ul data-role="listview">/*A la lista le aplicamos el data-role listview*/
  <li><a href="#1"><img src="img/foto1.png" width="100" height="100"/><h3>Elemento1</h3></a></li> /*En cada elemento metemos un enlace, una imagen (tamaño 100+100) y un título h3*/
  <li><a href="#2"><img src="img/foto2.png" width="100" height="100"/><h3>Elemento2</h3></a></li>
  <li><a href="#3"><img src="img/foto3.png" width="100" height="100"/><h3>Elemento3</h3></a></li>
</ul>

Esto es muy básico, vamos con algo más chulo: el mismo ejemplo, pero con un texto más pequeño debajo del título y con divisores:

<ul data-role="listview" data-inset="true" data-autodividers="true" data-filter="true">/*A la lista le aplicamos el data-role listview y el resto de configuración*/
  <li><a href="#1"><img src="img/foto1.png" width="100" height="100"/><h3>Elemento1</h3>
<p>Este es el primer elemento</p></a></li> /*En cada elemento metemos un enlace, una imagen (tamaño 100+100) y un título h3, y además una pequeña descripción*/
  <li><a href="#2"><img src="img/foto2.png" width="100" height="100"/><h3>Elemento2</h3>
<p>Este es el segundo elemento</p></a></li>
  <li><a href="#3"><img src="img/foto3.png" width="100" height="100"/><h3>Elemento3</h3>
<p>Este es el tercer elemento</p></a></li>
  <li><a href="#3"><img src="img/foto3.png" width="100" height="100"/><h3>Forma1</h3>
<p>Este es un elemento con otra letra para que se vea el divider</p></a></li> /**Y este último... para que se vea el divisor*/
</ul>

Y con este simple ejemplo puedes darle vida a tus listas.

Grave fallo de seguridad en Explorer

Desde OSI informan hoy que se ha encontrado una grave vulnerabilidad en Internet Explorer, que compromete al equipo en caso de visitar webs infectadas con malware, desde la versión 7 hasta la 10 (ambas inclusive) en los sistemas operativos Windows XP y Windows 7 (de Vista no dicen nada).

De momento Microsoft no ha sacado actualización ni parche, pero se espera que próximamente aparezca una actualización de seguridad. De momento recomiendan tener actualizado Microsoft EMET.

Yo personalmente lo que recomiendo es pasarse a Linux, pero allá cada cual.

PHPExcel: Exportar e importar archivos ods, xls y xlsx

En PHP tenemos una clase que nos da utilidades para trabajar con hojas de cálculo, PHPExcel. Ya habíamos hablado antes sobre cómo trabajar con PHP y archivos CSV, pero con esta librería podemos trabajar directamente con archivos de hoja de cálculo. Nos permite generar documentos xls, xlsx, ods, pdf… formatear las celdas, aplicar fórmulas, validar datos… e importar hojas de cálculo.

Si descargáis el proyecto desde GitHub os econtraréis con un montón de ejemplos sobre cómo llevar a cabo distintas acciones, aquí vamos a recoger sólo uno, el más básico de creación de un archivo, traduciendo al castellano los comentarios:

error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
date_default_timezone_set('Europe/London');

define('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');

/** Cargamos la librería PHPExcel */
require_once '../Build/PHPExcel.phar';


// Creamos un objeto PHPExcel
echo date('H:i:s') , " Create new PHPExcel object" , EOL;
$objPHPExcel = new PHPExcel();

// Definimos las propiedades del documento
echo date('H:i:s') , " Set document properties" , EOL;
$objPHPExcel->getProperties()->setCreator("Creador")
->setLastModifiedBy("Creador")
->setTitle("PHPExcel Test Document")
->setSubject("PHPExcel Test Document")
->setDescription("Documento de Excel creado por clases PHP.")
->setKeywords("office PHPExcel php")
->setCategory("Resultado de la prueba");


// Añadimos datos
echo date('H:i:s') , " Add some data" , EOL;
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'Hello')
->setCellValue('B2', 'world!')
->setCellValue('C1', 'Hello')
->setCellValue('D2', 'world!');

// Comprobamos que la codificación UTF-8 vaya bien
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A4', 'Miscellaneous glyphs')
->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');

// Renombrar la hoja de trabajo
echo date('H:i:s') , " Rename worksheet" , EOL;
$objPHPExcel->getActiveSheet()->setTitle('Simple');


// Definimos la hoja de cálculo activa
$objPHPExcel->setActiveSheetIndex(0);


// Escribimos el resultado en una hoja de Excel 2007 (xlsx)
echo date('H:i:s') , " Write to Excel2007 format" , EOL;
$callStartTime = microtime(true);

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
$callEndTime = microtime(true);
$callTime = $callEndTime - $callStartTime;

echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;

// Ahora salvamos los datos en Excel clásico
echo date('H:i:s') , " Write to Excel5 format" , EOL;
$callStartTime = microtime(true);

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save(str_replace('.php', '.xls', __FILE__));
$callEndTime = microtime(true);
$callTime = $callEndTime - $callStartTime;

echo date('H:i:s') , " File written to " , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;
echo 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , " seconds" , EOL;

// Imprimimos en pantalla que se ha finalizado el trabajo.
echo date('H:i:s') , " Done writing files" , EOL;
echo 'Files have been created in ' , getcwd() , EOL;

Como ya he dicho antes, la documentación incluye un montón de ejemplos, casi 40, así que podréis sacar de ahí mucha ayuda. Con esta librería podrás complacer a los clientes que exigen sacar los resultados de las consultas directamente a hojas de cálculo, por ejemplo.

Eliminar un directorio y su contenido en PHP

Estos días en uno de los proyectos del curro (váis a disculpar que esta semana sólo haya publicado citas, pero ha sido una semana dura en lo laboral y peor en lo personal) he tenido que hacer una función que vacíe un directorio completamente y lo borre en PHP. Alguna dirá rmdir y al carajo… pero cualquier usuario de linux/sistemas unix sabe que a ese rmdir le tienes que poner un -r para que borre los archivos que contiene, como no hay -r en PHP lo vamos a crear nosotros:

<?php
    function rmDir_rf($carpeta)
    {
      foreach(glob($carpeta . "/*") as $archivos_carpeta){             
        if (is_dir($archivos_carpeta)){
          rmDir_rf($archivos_carpeta);
        } else {
        unlink($archivos_carpeta);
        }
      }
      rmdir($carpeta);
     }

Explicación: Usamos glob para accedera todo lo que hay en la carpeta y lo recorremos (foreach). Si encontramos un directorio (is_dir nos lo confirma) entonces tiramos de recursivdad y ejecutamos la propia función dentro de si misma. Si no es un directorio, pues se borra el archivo. Al acabar de patear se borra la carpeta, que ahora que está vacía sí puede ser eliminada por rmdir.

Esta funcionalidad irá incluída en mi librería de seguridad DonnieSecure (próximamente en GitHub)

Tutorial de IdexedDB

El almacenamiento en el navegador se está convirtiendo en algo fundamental para el desarrollo de aplicaciones web con HTML5 y Javascript. En un primer momento parecía que WebSQL se iba a convertir en el standar, apoyado por Google y Apple en sus navegadores basados en Webkit. Pero la oposición de Microsoft y, sobre todo, de Mozilla sumada al auge de las bases de datos no relacionales en el ámbito del desarrollo móvil, ha hecho que IndexedDB se postule como el nuevo standar para almacenamiento en estos desarrollos. Desde 2010 la W3C ha dado por obsoleto WebSQL.

Todavía no me he puesto a trabajar con él en profundidad, pero os traigo aquí un tutorial basado en este de HTML5Rocks donde se nos explica cómo migrar de WebSQL a IndexedDB.

El ejemplo es una base de datos para un TODO list. Con WebSQL simplemente operábamos como si de una base de datos SQL se tratara, pero el concepto de IdexedDB es distinto. Se trata de un almacén de objetos Javascript donde guardamos parejas de valores: una clave y el objeto. Las búsquedas no se hacen con una query sino que se realiza una consulta sobre un índice que luego es iterado.

El primer paso con IdexedDB es abrir una base de datos:

window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;

// Manejando el prefijo de Chrome para IDBTransaction/IDBKeyRange.
if ('webkitIndexedDB' in window) {
  window.IDBTransaction = window.webkitIDBTransaction;
  window.IDBKeyRange = window.webkitIDBKeyRange;
}

indexedDB.db = null;

// Para depurar enviamos los errores a la consola
indexedDB.onerror = function(e) {
  console.log(e);
};

Arriba ya tenemos abierta una base de datos. Lo segundo, y también fundamental, es crear un almacén de objetos, igual que creamos tablas cuando trabajamos con una base de datos SQL.

indexedDB.open = function() {
  var request = indexedDB.open("todos");

  request.onsuccess = function(e) {
    var v = "2.0 beta"; // puedes poner cadenas en el nombre de la versión
    todoDB.indexedDB.db = e.target.result;
    var db = todoDB.indexedDB.db;
    // En la transacción setVersión es donde podemos crear los almacenes
    if (v!= db.version) {
      var setVrequest = db.setVersion(v);

      // para poder crear almacenes tenemos que hacerlo en onsuccess
      setVrequest.onfailure = todoDB.indexedDB.onerror;
      setVrequest.onsuccess = function(e) {
        if (db.objectStoreNames.contains("todo")) {
          db.deleteObjectStore("todo");
        }

        var store = db.createObjectStore("todo", {keyPath: "timeStamp"});

        var transaction = e.target.result;
        transaction.oncomplete = function() {
          todoDB.indexedDB.getAllTodoItems();
        }
      };
    } else {
      todoDB.indexedDB.getAllTodoItems();
    }
  };

  request.onfailure = todoDB.indexedDB.onerror;
};

Aquí hemos abierto el almacén todos, tras ello comprobamos que la versión de la base de datos sea diferente a la que estamos definiendo. En caso de que no lo sea, con setVersion creamos el nuevo almacén. El único sitio donde podemos modificar la estructura de la base de datos es en setVersion, donde se nos permite crear y eliminar almacenes de objetos.

El siguiente paso es ver cómo podemos añadir objetos a la colección. Para ello creamos la función addTodo.

indexedDB.addTodo = function() {
  var db = todoDB.indexedDB.db;
  var trans = db.transaction(['todo'], 'readwrite');
  var store = trans.objectStore('todo');

  var data = {
    "text": todoText, // el texto debe ser visible aquí
    "timeStamp": new Date().getTime()
  };

  var request = store.put(data);

  request.onsuccess = function(e) {
    todoDB.indexedDB.getAllTodoItems();
  };

  request.onerror = function(e) {
    console.log("Error Adding: ", e);
  };
};

Este método addTodo comienza cogiendo una referencia a la base de datos, seguimos definiendo una transacción readwrite y obtenemos una referencia a la coleccion de objetos. Luego creamos los datos como un objeto JSON y lo metemos en la base con el método put. Guardaremos el texto y un timestamp que servirá como clave única. Definimos que se re-renderizará en caso de éxito y que en caso de error se enviará a la consola.

Y si podemos insertar datos, desde luego podemos también borrarlos. Para ello crearemos el método deleteTodos:

indexedDB.deleteTodo = function(id, text) {
  if (confirm("Are you sure you want to Delete " + text + "?")) {
    var db = todoDB.indexedDB.db;
    var trans = db.transaction(["todo"], 'readwrite');
    var store = trans.objectStore("todo");

    var request = store.delete(id);

    request.onsuccess = function(e) {
      todoDB.indexedDB.getAllTodoItems();
    };

    request.onerror = function(e) {
      console.log("Error Adding: ", e);
    };
  }
};

El funcionamiento es similar al anterior método, pero con un delete en lugar del put, que recibe la clave del objeto para ser borrado.

Finalmente vamos con la lectura e impresioń de datos en pantalla, que a fin de cuentas es lo que nos importa en estos casos. Si queremos almacenar algo es para poder recuperarlo posteriormente.

function showAll() {
  document.getElementById("ourList").innerHTML = "";

  var request = window.indexedDB.open("todos");
  request.onsuccess = function(event) {
    // Enumerar el almacén de objetos completo.
    var db = todoDB.indexedDB.db;
    var trans = db.transaction(["todo"], 'readonly');
    var request = trans.objectStore("todo").openCursor();
    var ul = document.createElement("ul");

    request.onsuccess = function(event) {
      // Esto es un hack para versiones antiguas de Firefox (older versions than 6)
      var cursor = request.result || event.result;

      // Cuando el cursor esté a nulo es que hemos terminado la enumeración, por lo que
      // actualizamos el DOM
      if (!cursor) {
        document.getElementById("ourList").appendChild(ul);
        return;
      }

      var li = document.createElement("div");
      li.textContent = "key: " + cursor.key + " => Todo text: " + cursor.value.text;
      ul.appendChild(li);
      cursor.continue();
    }
  }
}

La idea en el caso de mostrar los resultados es abrir la transacción como readonly, creamos una lista (para este caso) y en cada iteración del cursor creamos un elemento li con un div dentro con los datos que vamos agregando a la lista. Cuando se termine el cursor, en la última iteración, añadimos la lista al DOM.

Como apreciación he de decir que IndexedDB, aunque desde luego es muy útil, tiene cosas que me parecen innecesariamente complicadas. Tal vez sea porque vengo del mundo de las bases de datos SQL pero WebSQL me parecía más claro y usable. Y con todo yo estoy acostumbrado a trabajar con Javascript (reconozco que nunca cosas muy complejas), no quiero imaginarme a muchos programadores que no tocan jamás el lado del cliente.

Hacer un UPSERT en MySQL

Si el otro día os contaba cómo hacer un INSERT IF NOT EXISTS en MySQL, hoy vamos a ver cómo hacer un UPSERT. La idea es intentar un INSERT, pero en caso de que se de una duplicidad de un campo único (una clave primaria, un campo UNIQUE…) en lugar de insertar actualizará el campo en cuestión. Hasta esta mañana desconocía esta forma de insertar, pero me lo comentaron en StackOverflow por un problemilla que tenía con un procedimiento almacenado.

La sintaxis sería más o menos:

INSERT INTO tabla (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1, b=2;

Os pongo un ejemplo práctico, metido dentro de un procedimiento almacenado. Recibe el id de un usurio y una variable bit que representa si se ha conectado o ha cerrado sesión, guarda estos datos junto con el momento en que se ha realizado dicha acción en una tabla usada para llevar el control de lo mismo (bueno, es más o menos lo mismo que me pusieron en SO):

DELIMITER $$
CREATE PROCEDURE `sp_UltimoLogin`(id_in int, accion_in bit)
BEGIN
  INSERT INTO `login` (`idusuario`, `fecha`, `accion`) VALUES (id_in, now(), accion_in)
    ON DUPLICATE KEY UPDATE `fecha` = now(), `accion` = accion_in;
END $$

Un truquito que os ahorrará realizar comprobaciones en muchos supuestos, aligerando la carga de trabajo y reduciendo líneas de código.

Mailvelope: encriptar correos de Gmail en Chrome con GPG

Mailvelope es un complemento de Chrome que nos permite utilizar GPG para encriptar nuestros correos. De momento para Firefox no está disponible pero podéis descargar desde GitHub el código y compilarlo.

Si sois novatos en esto de la criptografía os diré que GPG funciona como un sistema criptográfico asimétrico. Ya he hablado de esto antes, pero resumiendo rápidamente hay dos claves, una pública que puede saber cualquiera y una privada que sólo tú sabes. Si quieres enviar un correo encriptado usas la clave pública del receptor para encriptarlo, y ese correo sólo podrá ser leído si se usa la clave privada para desencriptarlo.

Lo primero, tras la instalación, es generar una clave. Podéis hacerlo pulsando el icono que tenéis arriba a la derecha. En el submenú desplegable elegís Options.

Icono del navegador Mailvelope

En el menú de la izquierda seleccionáis Generate Key y ahí veréis un menú como el de la imagen de debajo donde podéis elegir el algoritmo y la longitud de clave, la contraseña que usaréis para desencriptar con vuestra clave privada y varios datos como el correo o el nombre.

Generar clave Mailvelope

El par de claves que creamos debe aparecerá en Display keys. La seleccionamos y hacemos click en Export » Display public key, como puedes ver en la imagen. Puedes elegir entre exportarla a un fichero o copiar el texto y subirlo a un servidor de llaves públicas.

Ok ¿cómo enviar un correo? Es simple. Lo primero es que tenéis que añadir a vuestro llavero/keyring la clave del usuario al que le queréis enviar el correo, que podéis importar desde el menú de opciones (como ya hemos dicho en el párrafo anterior, los usuarios pueden publicar su clave pública en un servidor de llaves o enviarte un archivo con ella).

Importando clave
Menú de importación de claves

Una vez tienes tu clave entras en tu webmail (es compatible con varios) y desde allí ya verás a la derecha un icono como el de la imagen cuando empieces a redactar.

icono de redactar Mailvelope

Si pulsas en él se te abrirá una ventana modal como la de la siguiente foto. En ella puedes redacatar el correo normalmente. Si pulsas el icono con forma de candado te abrirá un menú donde eliges la clave pública del receptor y, aceptando al clickar en Transfer, generará el mensaje encriptado. Luego simplemente envías de forma habitual.

redactar correo encriptado

Para leerlos es más simple, tan pronto recibas un correo encriptado con tu clave pública sólo tendrás que hacer click, meter tu clave privada y leer.

Así que ya puedes gozar de seguridad en tus envíos confidenciales sin necesidad de romperte mucho la cabeza.