Está en la página 1de 8

Hoja de trucos de almacenamiento

criptográfico
Introducción
Este artículo proporciona un modelo simple a seguir al implementar soluciones
para proteger los datos en reposo.

Las contraseñas no deben almacenarse utilizando cifrado reversible; en su


lugar, deben usarse algoritmos de hash de contraseña segura. La hoja de
trucos de almacenamiento de contraseñas contiene más orientación sobre el
almacenamiento de contraseñas.

Diseño arquitectonico
El primer paso en el diseño de cualquier aplicación es considerar la
arquitectura general del sistema, ya que esto tendrá un gran impacto en la
implementación técnica.

Este proceso debe comenzar considerando el modelo de amenaza de la


aplicación (es decir, contra quién está tratando de proteger esos datos).

El uso de sistemas de gestión de claves o secretos dedicados puede


proporcionar una capa adicional de protección de seguridad, así como hacer
que la gestión de secretos sea significativamente más fácil, sin embargo, tiene
el costo de una complejidad adicional y una sobrecarga administrativa, por lo
que puede no ser factible para todas las aplicaciones. . Tenga en cuenta que
muchos entornos de nube proporcionan estos servicios, por lo que se deben
aprovechar cuando sea posible.

Dónde realizar el cifrado


El cifrado se puede realizar en varios niveles en la pila de aplicaciones, como:

 A nivel de aplicación.
 En el nivel de la base de datos (por ejemplo, SQL Server TDE
 En el nivel del sistema de archivos (por ejemplo, BitLocker o LUKS)
 A nivel de hardware (p. Ej., Tarjetas RAID cifradas o SSD)

Las capas más apropiadas dependerán del modelo de amenaza. Por ejemplo,
el cifrado a nivel de hardware es efectivo para proteger contra el robo físico
del servidor, pero no proporcionará protección si un atacante puede
comprometer el servidor de forma remota.
Minimice el almacenamiento de información
confidencial
La mejor manera de proteger la información confidencial es no almacenarla en
primer lugar. Aunque esto se aplica a todo tipo de información, con mayor
frecuencia se aplica a los detalles de la tarjeta de crédito, ya que son muy
deseables para los atacantes, y PCI DSS tiene requisitos tan estrictos sobre
cómo deben almacenarse. Siempre que sea posible, se debe evitar el
almacenamiento de información confidencial.

Algoritmos
Para el cifrado simétrico, AES con una clave de al menos 128
bits (idealmente 256 bits ) y un modo seguro debe usarse como el algoritmo
preferido.

Para el cifrado asimétrico, utilice la criptografía de curva elíptica (ECC) con


una curva segura como Curve25519 como algoritmo preferido. Si ECC no está
disponible y se debe utilizar RSA , asegúrese de que la clave tenga al
menos 2048 bits .

Hay muchos otros algoritmos simétricos y asimétricos disponibles que tienen


sus propios pros y contras, y pueden ser mejores o peores que AES o
Curve25519 en casos de uso específicos. Al considerar estos, se deben tener
en cuenta una serie de factores, que incluyen:

 Tamaño clave
 Ataques conocidos y debilidades del algoritmo.
 Madurez del algoritmo.
 Aprobación por parte de terceros, como el programa de validación algorítmica de
NIST .
 Rendimiento (tanto para cifrado como descifrado).
 Calidad de las bibliotecas disponibles.
 Portabilidad del algoritmo (es decir, qué tan ampliamente soportado es).

En algunos casos puede haber requisitos reglamentarios que limitan los


algoritmos que se pueden usar, como FIPS 140-2 o PCI DSS .

Algoritmos personalizados
No hagas esto.

Modos de cifrado
Hay varios modos que se pueden usar para permitir que los cifrados de bloque
(como AES) cifren cantidades arbitrarias de datos, de la misma manera que lo
haría un cifrado de flujo. Estos modos tienen diferentes características de
seguridad y rendimiento, y una discusión completa de ellos está fuera del
alcance de esta hoja de trucos. Algunos de los modos tienen requisitos para
generar vectores de inicialización (IV) seguros y otros atributos, pero estos
deben ser manejados automáticamente por la biblioteca.

Donde esté disponible, siempre se deben usar modos autenticados. Estos


proporcionan garantías de la integridad y autenticidad de los datos, así como
la confidencialidad. Los modos autenticados más utilizados son GCM y CCM ,
que deben usarse como primera preferencia.

Si GCM o CCM no están disponibles, se debe utilizar el modo CTR o


el modo CBC . Como estos no proporcionan ninguna garantía sobre la
autenticidad de los datos, se debe implementar una autenticación por
separado, como el uso de la técnica Encrypt-then-MAC . Se debe tener
cuidado al usar este método con mensajes de longitud variable

Si se requiere acceso aleatorio a los datos cifrados, se debe utilizar el


modo XTS . Esto generalmente se usa para el cifrado de disco, por lo que es
poco probable que lo use una aplicación web.

El BCE no debe usarse fuera de circunstancias muy específicas.

Generación segura de números aleatorios


Se necesitan números aleatorios (o cadenas) para varias funciones críticas de
seguridad, como generar claves de cifrado, IV, ID de sesión, tokens CSRF o
tokens de restablecimiento de contraseña. Como tal, es importante que estos
se generen de forma segura y que un atacante no pueda adivinarlos ni
predecirlos.

Por lo general, no es posible que las computadoras generen números


verdaderamente aleatorios (sin hardware especial), por lo que la mayoría de
los sistemas e idiomas proporcionan dos tipos diferentes de aleatoriedad.

Los generadores de números pseudoaleatorios (PRNG) proporcionan una


aleatoriedad de baja calidad que es mucho más rápida y se puede usar para
la funcionalidad no relacionada con la seguridad (como ordenar resultados en
una página o aleatorizar elementos de IU). Sin embargo, no deben usarse
para nada crítico para la seguridad, ya que a menudo es posible que los
atacantes adivinen o predigan la salida.

Los generadores de números pseudoaleatorios criptográficamente seguros


(CSPRNG) están diseñados para producir una calidad de aleatoriedad mucho
más alta (más estrictamente, una mayor cantidad de entropía), lo que los hace
seguros de usar para una funcionalidad sensible a la seguridad. Sin embargo,
son más lentos e intensivos en CPU, pueden terminar bloqueándose en
algunas circunstancias cuando se solicitan grandes cantidades de datos
aleatorios. Como tal, si se necesitan grandes cantidades de aleatoriedad no
relacionada con la seguridad, puede que no sean apropiadas.

La siguiente tabla muestra los algoritmos recomendados para cada idioma, así
como las funciones inseguras que no se deben usar.
Funciones criptográficamente
Idioma Funciones inseguras
seguras

C random(), rand() getrandom (2)

Java java.util.Random() java.security.SecureRandom

random_bytes () , random_int
() en PHP 7
PHP rand(), mt_rand(), array_rand(),uniqid()
o openssl_random_pseudo_bytes
() en PHP 5

.NET /
Random(), RNGCryptoServiceProvider
C#

C
arc4random() (Utiliza RC4 Cipher), SecRandomCopyBytes
objetivo

Pitón random(), misterios()

Rubí Random, SecureRandom

Vamos randusando el math/randpaquete, paquete crypto.rand

rand :: prng :: chacha ::


ChaChaRng y el resto de
Oxido rand::prng::XorShiftRng,
los CSPRNG de la biblioteca
Rust .

UUID y GUID
Los identificadores universalmente únicos (UUID o GUID) a veces se usan
como una forma rápida de generar cadenas aleatorias. Aunque pueden
proporcionar una fuente razonable de aleatoriedad, esto dependerá del tipo o
versión del UUID que se cree.

Específicamente, los UUID de la versión 1 se componen de una marca de


tiempo de alta precisión y la dirección MAC del sistema que los generó, por lo
que no son aleatorios (aunque pueden ser difíciles de adivinar, dado que la
marca de tiempo está en los 100ns más cercanos). Los UUID de tipo 4 se
generan aleatoriamente, aunque si esto se hace utilizando un CSPRNG
dependerá de la implementación. A menos que se sepa que esto es seguro en
el lenguaje o marco específico, no se debe confiar en la aleatoriedad de los
UUID.
Defensa en profundidad
Las aplicaciones deben estar diseñadas para ser seguras, incluso si fallan los
controles criptográficos. Cualquier información almacenada en forma
encriptada también debe estar protegida por capas adicionales de
seguridad. La aplicación tampoco debe confiar en la seguridad de los
parámetros de URL encriptados, y debe imponer un control de acceso sólido
para evitar el acceso no autorizado a la información.

Gestión de claves
Procesos
Los procesos formales deben implementarse (y probarse) para cubrir todos los
aspectos de la gestión de claves, incluidos:

 Generando y almacenando nuevas claves.


 Distribuir llaves a las partes requeridas.
 Implementación de claves en servidores de aplicaciones.
 Rotación y desmantelamiento de llaves antiguas

Generación clave
Las claves deben generarse aleatoriamente utilizando una función
criptográficamente segura, como las que se analizan en la sección Generación
segura de números aleatorios . Las claves no deben basarse en palabras o
frases comunes, o en caracteres "aleatorios" generados al machacar el
teclado.

Cuando se utilizan varias claves (como las claves de cifrado de datos y de


cifrado de datos separadas de datos), deben ser completamente
independientes entre sí.

Vida clave y rotación


Las claves de cifrado se deben cambiar (o rotar) en función de varios criterios
diferentes:

 Si se sabe (o se sospecha) que la clave anterior se ha visto comprometida.


o Esto también podría ser causado por alguien que tenía acceso a la clave que
abandonaba la organización.
 Después de que haya transcurrido un período de tiempo especificado (conocido
como el criptoperíodo).
o Hay muchos factores que podrían afectar qué es un criptoperíodo apropiado,
incluido el tamaño de la clave, la sensibilidad de los datos y el modelo de
amenaza del sistema. Consulte la sección 5.3 de NIST SP 800-57 para
obtener más orientación.
 Después de que la clave se haya utilizado para cifrar una cantidad específica de
datos.
o Esto normalmente sería 2^35bytes (~ 34GB) para claves de 64 bits
y 2^68bytes (~ 295 exabytes) para claves de 128 bits.
 Si hay un cambio significativo en la seguridad proporcionada por el algoritmo
(como un nuevo ataque anunciado).

Una vez que se cumple uno de estos criterios, se debe generar una nueva
clave y utilizarla para cifrar cualquier dato nuevo. Hay dos enfoques principales
sobre cómo se deben manejar los datos existentes que se cifraron con las
claves antiguas:

1. Descifrarlo y volver a cifrarlo con la nueva clave.


2. Marcar cada elemento con la ID de la clave que se utilizó para cifrarlo y almacenar
varias claves para permitir que se descifren los datos antiguos.

En general, se debe preferir la primera opción, ya que simplifica enormemente


tanto el código de la aplicación como los procesos de administración de
claves; sin embargo, no siempre es factible. Tenga en cuenta que las claves
antiguas generalmente deben almacenarse durante un cierto período después
de que se hayan retirado, en caso de que sea necesario descifrar las copias
de seguridad antiguas de las copias de los datos.

Es importante que el código y los procesos necesarios para rotar una clave
estén en su lugar antes de que sean necesarios, de modo que las claves
puedan rotarse rápidamente en caso de compromiso. Además, los procesos
también deben implementarse para permitir que se modifique el algoritmo de
cifrado o la biblioteca, en caso de que se encuentre una nueva vulnerabilidad
en el algoritmo o la implementación.

Almacenamiento de claves
El almacenamiento seguro de claves criptográficas es uno de los problemas
más difíciles de resolver, ya que la aplicación siempre necesita tener cierto
nivel de acceso a las claves para descifrar los datos. Si bien es posible que no
sea posible proteger completamente las claves de un atacante que haya
comprometido completamente la aplicación, se pueden tomar una serie de
pasos para que sea más difícil obtener las claves.

Cuando esté disponible, se deben utilizar los mecanismos de almacenamiento


seguro proporcionados por el sistema operativo, el marco o el proveedor de
servicios en la nube. Éstos incluyen:

 Un módulo de seguridad de hardware físico (HSM).


 Un HSM virtual.
 Bóvedas clave como Amazon KMS o Azure Key Vault .
 API de almacenamiento seguro proporcionadas por la clase ProtectedData en
.NET framework.

Existen muchas ventajas al usar este tipo de almacenamiento seguro en lugar


de simplemente colocar claves en los archivos de configuración. Los detalles
de estos variarán dependiendo de la solución utilizada, pero incluyen:
 Gestión centralizada de claves, especialmente en entornos contenedorizados.
 Fácil rotación y reemplazo de teclas.
 Generación segura de claves.
 Simplificando el cumplimiento de los estándares regulatorios como FIPS 140 o
PCI DSS.
 Haciendo más difícil para un atacante exportar o robar claves.

En algunos casos, ninguno de estos estará disponible, como en un entorno de


alojamiento compartido, lo que significa que no es posible obtener un alto
grado de protección para las claves de cifrado. Sin embargo, todavía se
pueden seguir las siguientes reglas básicas:

 No codifique las claves en el código fuente de la aplicación.


 No verifique las claves en los sistemas de control de versiones.
 Proteja los archivos de configuración que contienen las claves con permisos
restrictivos.
 Evite almacenar claves en variables de entorno, ya que pueden quedar expuestas
accidentalmente a través de funciones como phpinfo () o a través
del /proc/self/environarchivo.

Separación de claves y datos


Siempre que sea posible, las claves de cifrado deben almacenarse en una
ubicación separada de los datos cifrados. Por ejemplo, si los datos se
almacenan en una base de datos, las claves deben almacenarse en el sistema
de archivos. Esto significa que si un atacante solo tiene acceso a uno de estos
(por ejemplo, a través del recorrido del directorio o la inyección de SQL), no
puede acceder a las claves y a los datos.
Dependiendo de la arquitectura del entorno, puede ser posible almacenar las
claves y los datos en sistemas separados, lo que proporcionaría un mayor
grado de aislamiento.

Cifrado de claves almacenadas


Siempre que sea posible, las claves de cifrado deben almacenarse en forma
cifrada. Se requieren al menos dos claves separadas para esto:

 La clave de cifrado de datos (DEK) se utiliza para cifrar los datos.


 La clave de cifrado de clave (KEK) se utiliza para cifrar el DEK.

Para que esto sea efectivo, el KEK debe almacenarse por separado del
DEK. El DEK cifrado se puede almacenar con los datos, pero solo se podrá
utilizar si un atacante también puede obtener el KEK, que se almacena en otro
sistema.

El KEK también debería ser al menos tan fuerte como el DEK. La guía
de cifrado de sobres de Google contiene más detalles sobre cómo administrar
DEK y KEK.
En arquitecturas de aplicaciones más simples (como los entornos de
alojamiento compartido) donde KEK y DEK no se pueden almacenar por
separado, este enfoque tiene un valor limitado, ya que es probable que un
atacante pueda obtener ambas claves al mismo tiempo. Sin embargo, puede
proporcionar una barrera adicional para los atacantes no calificados.

Se podría usar una función de derivación de clave (KDF) para generar un KEK
a partir de la entrada suministrada por el usuario (como una frase de
contraseña), que luego se usaría para cifrar un DEK generado
aleatoriamente. Esto permite que el KEK se cambie fácilmente (cuando el
usuario cambia su frase de contraseña), sin necesidad de volver a cifrar los
datos (ya que el DEK sigue siendo el mismo).

También podría gustarte