OpenSSL

S/MIME

S/MIME es un estándar para el envío y recepción de datos MIME seguros, especialmente en correo electrónico. Algunos clientes de correo proporcionan esta posibilidad automáticamente pero también se pueden realizar mediante la opción smime. Consulte la página de manual de smime 1) donde hay unos ejemplos variados.

Verificar un mensaje S/MIME firmado

Para verificar un mensaje mime firmado, ponemos:

 
openssl smime -verify -in msg.txt 
              

Si el certificado emisor está firmado por una CA, pueden aparecer varios mensajes de cabecera, y también una copia del mensaje junto con una nota sobre la verificación correcta.

En caso contrario, si la firma S/MIME no es correcta o no se reconoce a la autoridad certificadora aparecerán una indicaciones de error.

Muchos clientes de correo envían un copia del certificado público adjunto al mensaje. Desde la línea de órdenes puede ver los datos certificados. Con la opción smime -pk7out pasa mediante una tubería una copia del certificado a la opción pkcs7:

 
openssl smime -pk7out -in msg.txt | \
openssl pkcs7 -text -noout -print_certs 
              

Si lo que quiere es extraer una copia del certificado para uso posterior sólo tendría que usar la primera parte de la tubería:

 
openssl smime -pk7out -in msg.txt -out her-cert.pem 
              

Ahora puede integrarlo en su infraestructura OpenSSL o tenerlo para cualquier otro uso:

 
openssl smime -verify -in msg.txt -CAfile /path/to/her-cert.pem 
              

Cifrar un mensaje S/MIME

Supongamos que alguien le envía su certificado público y le solicita que le cifre algún mensaje. Ha guardado su certificado como her-cert.pem y quiere cifrar el mensaje en my-message.txt.

Si queremos usar el cifrado estándar, simplemente indicamos el fichero y el certificado::

 
openssl smime her-cert.pem -encrypt -in my-message.txt 
              

Si el destinatario dispone también de las herramientas SSL necesarias, puede especificar un algoritmo más robusto como triple DES:

 
openssl smime her-cert.pem -encrypt -des3 -in my-message.txt 
              

El mensaje cifradojunto con las cabecers se envía de a la entrada estándar, salvo que especifiquemos mediante -out un fichero concreto. También se puede usar la salida estándar para enviar el correo directamente a sendmail:

 
openssl smime her-cert.pem \
  -encrypt \
  -des3 \
  -in my-message.txt \
  -from 'Your Fullname <Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.>' \
  -to 'Her Fullname <Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.>' \
  -subject 'My encrypted reply' |\
sendmail Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo. 
              

Como firmo un mensaje S/MIME

Si no tiene necesidad de cifrar todo el mensaje y sí quiere firmarlo para asegurar la integridad tenemos que usar una receta similar al cifrado. La principal diferencia es que tiene que tener sus propias llave y certificado, ya que no puede firmar nada con el certificado del recipiente.

 
openssl smime \
  -sign \
  -signer /path/to/your-cert.pem \
  -in my-message.txt \
  -from 'Your Fullname <Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.>' \
  -to 'Her Fullname <Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.>' \
  -subject 'My encrypted reply' |\
sendmail Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo. 
              

Datos aleatorios

Generar bits aleatorios

Use la opción rand para generar datos binarios o base64-encoded.

# escribe 128 bits aleatorios en base64-a la salida estándar

 
openssl rand -base64 128 
            

# escribe 1024 bits en formato binario en un fichero

 
openssl rand -out random-data.bin 1024 
            

Hashes de contraseñas

Se pueden generar hashes mediante la opción passwd para interactuar con los ficheros tradicionales /etc/passwd, /etc/shadow y de contraseñas de Apache.

Generar el hash cifrado de una contraseña

Puede generar el hash de una forma muy simple:

 
openssl passwd miclave
1SVGewli74UQI 
              

Si ya la conoce puede incluir una semilla:

 
openssl passwd -salt F2  miclave
F2y5biqTazL0A 
              

hash estilo shadow password

 
openssl passwd -1 miclave
$1$fTI7WqzK$nvA95VAzkksmneO3nICMa/ 
              

La semilla en este formato consiste en los caracteres comprendidos entre el segund y tercer símbolos $.

 
openssl passwd -1 -salt F2  miclave
$1$F2$c8mTmVFjlaUMXv0nOSMzp0 
              

Llaves privadas

Generar una llave RSA

Utilizamos la opción genrsa

# usa una llave de 512-bit de forma predeterminada y muestra en la salida estándar

 
openssl genrsa 
              

# llave de 1024-bit key y el resultado en cert.key

 
openssl genrsa -out cert.key 1024 
              

# igual que antes pero cifrado con contraseña

 
openssl genrsa -des3 -out cert.key 1024 
              

Generar una llave RSA pública

La opción rsa produce una versión pública de la llave privada RSA:

 
openssl rsa -in cert.key -pubout 
              

Generar una llave DSA

La generación de una llave DSA requiere un fichero de parámetros y las operaciones de verificación son más lentas que las correspondientes a las llaves RSA.

Si sólo quiere generar unasimple llave DSA, puede hacerlo en un solo paso mediante la suborden dsaparam.

# la llave se llama dsakey.pem

 
openssl dsaparam -noout -out dsakey.pem -genkey 1024 
              

Si por otro lado pretende cear varias llaves DSA, es probable que antes le interese crear un fichero de parámetros compartido. Construir los parámetros se lleva su tiempo pero la generación se hace mucho más rápida.

# parámetros en dsaparam.pem

 
openssl dsaparam -out dsaparam.pem 1024 
              

# creamos la primera llave

 
openssl gendsa -out key1.pem dsaparam.pem 
              

# y el resto, ...

 
openssl gendsa -out key2.pem dsaparam.pem 
              

Eliminar una contraseña de una llave

Si el certificado lo utiliza un demonio, no es conveniente que las llaves estén protegidas con contraseña salvo que queramos introducir la contraseña cada vez que iniciamos el demonio. Si ya tenemos la llave con contraseña podemos desencriptarla para eliminar la necesidad de contraseña. El mecanismo depende del sistema de cifrado empleado.

Lo que haremos será crear una nueva versión de la llave sin contraseña.

# se le solicitará la contraseña por última vez

 
openssl rsa -in key.pem -out newkey.pem 
              

Con frecuencia se almacenan las llave privada y el certificado en el mismo fichero. En este caso tenemos que seguir dos pasos:

# hay que introducir la contraseña

 
openssl rsa -in mycert.pem -out newcert.pem
openssl x509 -in mycert.pem >>newcert.pem 
              

Cifrado/Decifrado

Codificar con base64-encode

Para codificar tenemos la opción enc -base64.

#La salida codificada de fichero.txt se muestra en la salida estándar.

 
openssl enc -base64 -in file.txt 
              

# Para enviar el resultado a un fichero.

 
openssl enc -base64 -in file.txt -out file.txt.enc 
              

También es posible realizar la codificación de una cadena desde la línea de órdenes:

 
$ echo -n "miclave" | openssl enc -base64
bWljbGF2ZQ== 
              

Hay que tener en cuenta que echo envía un fin de línea tras la cadena. Para evitarlo, especialmente cuando generamos contraseñas, debemos usar la opción -n. Si no se pone el valor es distinto:

 
echo "miclave" | openssl enc -base64
bWljbGF2ZQo= 
              

Podemos descifrar con la opción -d

 
echo bWljbGF2ZQo=| openssl enc -base64 -d-d
miclave 
              

Cifrar un fichero

Para el cifrado simple, probablemente es mejor usar herramientas como GPG, sin embargo puede haber situaciones que en las cuales es preferible utilizar openssl.

Para ecoger el mecanismo de cifrado podemos ejecutar

# ver el encabezado 'Cipher commands'

 
openssl -h 
              

# u obtener una lista

 
openssl list-cipher-commands 
              

Una vez que hemos elegido el mecanismo de cifrado, tendrá que decidir si tambien quiere la codficación base64-encode. Haciéndolo transformamos el fichero resultado en formato texto lo que puede facilitar su distribución por ejemplo por correo electrónico. Si omitimos la codificación base64-encode el fichero será binario.

# ciframos file.txt en file.enc usando 256-bit AES en modo CBC

 
openssl enc -aes-256-cbc -salt -in file.txt -out file.enc 
              

# igual con salida base64-encoded

 
openssl enc -aes-256-cbc -a -salt -in file.txt -out file.enc 
              

Para descifrar file.enc tendrá que indicar el cifrado y la contraseña

# descrifar el binario file.enc

 
openssl enc -d -aes-256-cbc -in file.enc 
              

# descifrar la versión base64-encoded

 
openssl enc -d -aes-256-cbc -a -in file.enc