------------------------------------------
   Openssl, recordatorio
   05 may 2023
   ------------------------------------------

   A raíz de la publicación de OpenSSL Cookbook 3ed [1] y de darme cuenta
   de que la gran mayoría de lo que pone en el libro no es relevante para
   mis necesidades decidí echar un vistazo a otras cosas en las que openssl
   sí puede ayudarme. Antes que nada:


   $ openssl version
   OpenSSL 1.1.1n  15 Mar 2022



   == Cifrado ==

   Una de las cosas que permite el programa es un cifrado simétrico con o
   sin cifrado añadido en base64. Vamos a hacer pruebas con un fichero de
   ejemplo


   $ cat fortuna.txt
   El mucho saber hace sabios, pero no dichosos.


   Veamos que algoritmos ofrece el programa:


   $ openssl enc -list
   Supported ciphers:
   -aes-128-cbc               -aes-128-cfb               -aes-128-cfb1
   -aes-128-cfb8              -aes-128-ctr               -aes-128-ecb

   ...

   -camellia-128-cbc          -camellia-128-cfb          -camellia-128-cfb1
   -camellia-128-cfb8         -camellia-128-ctr          -camellia-128-ecb
   -camellia-128-ofb          -camellia-192-cbc          -camellia-192-cfb

   ...

   -rc2-64-cbc                -rc2-cbc                   -rc2-cfb
   -rc2-ecb                   -rc2-ofb                   -rc4
   -rc4-40                    -seed                      -seed-cbc
   -seed-cfb                  -seed-ecb                  -seed-ofb
   -sm4                       -sm4-cbc                   -sm4-cfb
   -sm4-ctr                   -sm4-ecb                   -sm4-ofb


   Huh, si no cuento mal son 141 algoritmos. ¿Cuales son las
   recomendaciones actualmente? AES sigue siendo el estándar con razón,
   Blowfish empieza a tener unos años y su sucesor Twofish no aparece en la
   lista. Camellia es uno de los más seguros, la elección internacional por
   la organización ISO y el foro IETF.

   Vamos a usar Camellia, para ello vamos a empezar por generar una clave
   pseudoaleatoria de 256 bits usando el mismo programa.

   `openssl rand -out clave.bin 32`

   Utilizamos el fichero clave.bin como contraseña para el cifrado,


   $ openssl enc -camellia-256-cbc -in fortuna.txt \
                 -out fortuna.enc -pass file:clave.bin
   *** WARNING : deprecated key derivation used.
   Using -iter or -pbkdf2 would be better.


   openssl nos advierte de que haríamos mejor en usar un algoritmo de
   derivación de claves en lugar de (lo que podría ser) una clave insegura
   en clave.bin, sin embargo la hemos generado aleatoriamente así que
   podemos ignorar el aviso, fortuna.enc es un fichero cifrado de forma muy
   segura usando el algoritmo Camellia de 256 bits en modo CBC.


   $ file fortuna.enc
   fortuna.enc: openssl enc'd data with salted password


   Es un fichero binario, si quisiéramos compartirlo como texto (en un
   email o quizás en un foro público) añadiríamos a la orden anterior la
   opcion -base64.

   El resultado tiene este aspecto:


   U2FsdGVkX187oJ2dx9SYIlTOu41KbXsMf3HOM4pfekWn6dsg7ZmpxNoIgmbBeSxC
   /O4CrKStNo9jGL0KBF0INA==


   Ahora alguien en posesión de la clave con el fichero clave.bin podría
   descifrarlo haciendo


   openssl enc -d -camellia-256-cbc -in fortuna.enc \
               -out fortuna.txt -pass file:clave.bin


   == Hash ==

   openssl permite obtener resúmenes "hash" de cualquier fichero. Veamos
   que algoritmos permite usar (openssl usa el término digest, dgst):


   $ openssl dgst -list
   Supported digests:
   -blake2b512                -blake2s256                -md4
   -md5                       -md5-sha1                  -ripemd
   -ripemd160                 -rmd160                    -sha1
   -sha224                    -sha256                    -sha3-224
   -sha3-256                  -sha3-384                  -sha3-512
   -sha384                    -sha512                    -sha512-224
   -sha512-256                -shake128                  -shake256
   -sm3                       -ssl3-md5                  -ssl3-sha1
   -whirlpool


   Que son 25 de ellos. Los más recomendables parecen ser sha3, blake2 y sha2.

   Vamos a obtener el hash sha3 de 256 bits del fichero fortuna.txt


   openssl dgst -sha3-256 fortuna.txt
   SHA3-256(fortuna.txt)= b60bb27b986d060bcf99cd9aec39da080fe05df8c7fc16c36bb54b8791943ca0


   == Números aleatorios ==

   Para muchos procesos criptográficos es necesario tener números
   aleatorios (o al menos pseudo aleatorios), un proceso que me interesa
   especialmente.

   Vamos a generar 32 bytes aleatorios mostrando el resultado como
   hexadecimal


   openssl rand -hex 32
   d5e23d0a2765560667a42bb3e3159f55eabdbefafdfbf407e5be8f6b2a88da62


   Lo mismo pero con la salida en base64


   openssl rand -base64 32
   3nZEnbGAslE0YWGFLFYY/fem6rJ1C2GxffnG4umx9R4=


   Si tenemos un fichero con suficiente entropía podemos usarlo como opción
   poniendo -rand entropia.txt o mejor todavía si tenemos un dispositivo
   hardware generador de entropía hacer -engine (nombre).

   == Conclusión ==

   openssl es un programa realmente versátil. Además de las capacidades que
   hemos apenas arañado de su superficie permite generar claves, firmar y
   verificar archivos, verificar certificados, establecer comunicaciones
   seguras SSL/TLS...


   == Referencias ==

   [1] https://www.feistyduck.com/library/openssl-cookbook/

   [2] https://en.wikipedia.org/wiki/Symmetric-key_algorithm

   [3] https://csrc.nist.gov/