miércoles, 14 de agosto de 2019

Encriptación de columnas en PostgreSQL

PostgreSQL es una base de datos relacional ideal para diferentes escenarios, con una larga historia desde 1982 en el corazón de la Universidad de Berkeley hasta nuestros días. Entre sus características más notables destacan su alta concurrencia, la variedad de tipos de datos nativos, tratamiento de datos geométricos, soporte a transacciones distribuidas, drivers para multitud de lenguajes de programación, alta seguridad o su disponibilidad en entornos cloud como Azure o AWS.

Dentro de la materia de Seguridad, encontramos artefactos para implementar la encriptación mediante diferentes opciones (consultar la documentación oficial). Una de estas formas de encriptación la encontramos a nivel de columna, la cual podemos implementar a través de una extensión llamada pgcrypto. Para usar esta extensión, debemos crearla dentro de la base de datos en uso mediante el comando:

CREATE EXTENSION pgcrypto;


Ahora tenemos a nuestra disposición nuevas funciones para incorporar en el lenguaje SQL, a nivel de columna.

La primera función se llama PGP_SYM_ENCRYPT(), y permite encriptar un texto dado, mediante al algoritmo especificado. La siguiente sintaxis encripta mi nombre mediante el algoritmo AES-KEY:

PGP_SYM_ENCRYPT('Rafael','AES_KEY')

La segunda función se llama PGP_SYM_DECRYPT(), y desencripta la columna encriptada mediante el algoritmo especificado:

PGP_SYM_DECRYPT(nombre_columna::bytea, 'AES_KEY')


Ejemplo

Vamos a poner en práctica lo anterior. En primer lugar vamos a crear una tabla de usuarios, en donde almacenaremos los nombres de usuarios y su contraseña, la cual vamos a encriptar para evitar robo de contraseñas:

CREATE TABLE usuarios(nombre VARCHAR(50), password VARCHAR(255));

INSERT INTO usuarios (nombre, password) VALUES ('Rafael', PGP_SYM_ENCRYPT('mypassword','AES_KEY'));

Si se lista la información, veremos que la contraseña está encriptada:

SELECT nombre, password FROM usuarios;

Para ver los datos desencriptados, utilizaremos la siguiente sentencia:

SELECT nombre, pgp_sym_decrypt(password::bytea,'AES_KEY') FROM usuarios;

La siguiente sentencia cambia la contraseña, encriptando la misma:

UPDATE usuarios SET password=(PGP_SYM_ENCRYPT('newpassword', 'AES_KEY'));

Podemos hacer una búsqueda comparando el valor en plano con el valor desencriptado de la columna encriptada. En nuestro ejemplo, cuando hacemos un login, hemos de comparar el nombre y la contraseña. La siguiente sentencia resuelve el problema:

SELECT COUNT(*) AS coincidencias FROM usuarios WHERE nombre = 'Rafael' AND PGP_SYM_DECRYPT(password::bytea, 'AES_KEY') = 'newpassword';


Ver también




domingo, 9 de septiembre de 2018

Contenido pornográfico en la red social Google Plus

Estoy realizando un Máster de Big Data y Business Intelligence aplicado a la empresa y al eCommerce. En el módulo de Community Manager, debo hacer un ejercicio estudiando al Community Manager de una empresa de mi elección, y de cómo hace su trabajo en las diferentes redes sociales.

La empresa de mi elección ha sido Google. Cuando he buscado a Google en su propia red social, Google Plus, me he llevado la sorpresa de que, tras los resultados de páginas y colecciones, en las primeras posiciones, aparecen artículos o publicaciones de contenido pornográfico.


¿Cómo le puede pasar ésto a Google? ¿Se ha producido un fallo en su filtro? ¿Ha fallado su Inteligencia Artificial? ¿Cómo puede permitir esto?

miércoles, 1 de marzo de 2017

Ionic 2: Selección de fecha y hora (2)

Este artículo viene a añadir más posibilidades a la app creada en el artículo "Ionic2: Selección de fecha y hora".

Selección del mes por su nombre

A la hora de mostrar el mes, tanto para su selección como para su visualización, debemos conocer el formato que nos ofrece el componente DateTime de Ionic 2. La propiedad displayFormat posee un rico repertorio de posibilidades para configurar esto. En el caso del mes, tenemos estos formatos:
  • M: Número de mes (1..12)
  • MM: Número de mes (01..12)
  • MMM: Nombre corto de mes (Jan, Feb...)
  • MMMM: Número completo del mes (January, February...)

Por defecto, los nombres vienen dados en inglés, pero es posible modificar sus literales a través de las siguientes propiedades:
  • monthNames="Enero, Febrero...": Especifica los literales para los nombres completos
  • monthShortNames="Ene, Feb...": Especifica los literales para los nombres cortos


Para ver ésto en acción, podemos añadir otra tarjeta al ejemplo:



Formatos de fecha y hora

En la siguiente lista se muestran todos los formatos disponibles para la fecha:
  • YYYY: Año en cuatro dígitos (2017)
  • YY: Año en dos dígitos
  • M: Número de mes (1..12)
  • MM: Número de mes (01..12)
  • MMM: Nombre corto del mes (January)
  • MMMM: Nombre completo del mes (Jan)
  • D: Número del día (1..31)
  • DD: Número del día (01..31)
  • DDD: Nombre Corto del día (Mon)
  • DDDD: Nombre completo del día (Monday)


En esta otra lista se muestran todos los formatos disponibles para la hora:
  • H: Hora en formato 24h (1..23)
  • HH: Hora en formato 24h (01..23)
  • h: Hora en formato 12h (1..12)
  • hh: Hora en formato 12h (01..12)
  • m: Minuto (0..59)
  • mm: Minuto (00..59)
  • s: Segundo (0..59)
  • ss: Segundo (00..59)
  • a: Período 12h (am / pm)
  • A: Período 12h (AM / PM)


Para modificar los literales de los nombres:
  • monthNames="Enero, Febrero...": Nombres completos del mes
  • monthShortNames="Ene, Feb...": Nombres cortos del mes
  • dayNames="Domingo, Lunes...": Nombres completos del día
  • dayShortNames="Dom, Lun...": Nombres cortos del día


Formato ISO 8601

Los valores de fecha del componente DateTime no trabajan con el tipo Date de JavaScript, a fin de evitar problemas de parseo o de formateo de los valores. En su lugar, utiliza el formato string (cadena de texto), utilizando la sintaxis de ISO 8601: YYYY-MM-DDTHH:mm:ssZ

Sin embargo, ISO 8601 permite trabajar en diferentes formatos:
  • YYYY: Año (2017)
  • YYYY-MM: Año y mes (2017-03)
  • YYYY-MM-DD: Fecha completa (2017-03-01)
  • YYYY-MM-DDTHH:mm: Fecha y hora (2017-03-01T15:04
  • YYYY-MM-DDTHH:mm:ssTZD: Zona horaria UTC (2017-03-01T15:04:37.598Z)
  • YYYY-MM-DDTHH:mm:ssTZD: Zona horaria Offset (2017-03-01T15:04:37.598+1:00)
  • HH:mm: Hora y minuto (15:04)
  • HH:mm:ss: Hora, minuto y segundo (15:04:37)


displayFormat y pickerFormat

La propiedad displayFormat del componente DateTime especifica cómo visualizar el valor de la fecha/hora dentro del propio componente.

La propiedad pickerFormat especifica qué columnas, en qué orden y en qué formato se muestran los campos a seleccionar por el componente DateTime




Rango de fechas

Las propiedades min y max del componente DateTime definen la fecha mínima y máxima que se puede seleccionar. En el ejemplo habíamos introducido únicamente el año, por lo que asume, por defecto, el 1 de Enero de el año para la propiedad min, y el 31 de Diciembre para el año en la propiedad max.

Para especificar rangos más concretos, se debe concretar las fechas en formato YYYY-MM-DD. Por ejemplo, para especificar un rango entre el 15 de Mayo y el 30 de Junio de 2017, la configuración sería la siguientes:

min="2017-05-15" max="2017-06-30"

Enlaces de interés