Quiero encriptar y desencriptar un archivo usando una contraseña.
¿Cómo puedo usar OpenSSL para hacer eso?
Quiero encriptar y desencriptar un archivo usando una contraseña.
¿Cómo puedo usar OpenSSL para hacer eso?
Respuestas:
Advertencia de seguridad : AES-256-CBC no proporciona cifrado autenticado y es vulnerable a los ataques de relleno de oráculo . Deberías usar algo como la edad en su lugar.
Cifrar:
openssl aes-256-cbc -a -salt -in secrets.txt -out secrets.txt.enc
Descifrar:
openssl aes-256-cbc -d -a -in secrets.txt.enc -out secrets.txt.new
-md sha256
a su comando de codificación y decodificación si planea usar este archivo en otra máquina. Eso debería cubrirlo contra las incompatibilidades / diferencias de la versión OpenSSL
Es probable que desee utilizar en gpg
lugar de openssl
ver las "Notas adicionales" al final de esta respuesta. Pero para responder la pregunta usando openssl
:
Encriptar:
openssl enc -aes-256-cbc -in un_encrypted.data -out encrypted.data
Para descifrar:
openssl enc -d -aes-256-cbc -in encrypted.data -out un_encrypted.data
Nota: Se le solicitará una contraseña cuando cifre o descifre.
Su mejor fuente de información openssl enc
probablemente sería: https://www.openssl.org/docs/man1.1.1/man1/enc.html
Línea de comando:
openssl enc
toma la siguiente forma:
openssl enc -ciphername [-in filename] [-out filename] [-pass arg]
[-e] [-d] [-a/-base64] [-A] [-k password] [-kfile filename]
[-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md] [-p] [-P]
[-bufsize number] [-nopad] [-debug] [-none] [-engine id]
Explicación de los parámetros más útiles con respecto a su pregunta:
-e
Encrypt the input data: this is the default.
-d
Decrypt the input data.
-k <password>
Only use this if you want to pass the password as an argument.
Usually you can leave this out and you will be prompted for a
password. The password is used to derive the actual key which
is used to encrypt your data. Using this parameter is typically
not considered secure because your password appears in
plain-text on the command line and will likely be recorded in
bash history.
-kfile <filename>
Read the password from the first line of <filename> instead of
from the command line as above.
-a
base64 process the data. This means that if encryption is taking
place the data is base64 encoded after encryption. If decryption
is set then the input data is base64 decoded before being
decrypted.
You likely DON'T need to use this. This will likely increase the
file size for non-text data. Only use this if you need to send
data in the form of text format via email etc.
-salt
To use a salt (randomly generated) when encrypting. You always
want to use a salt while encrypting. This parameter is actually
redundant because a salt is used whether you use this or not
which is why it was not used in the "Short Answer" above!
-K key
The actual key to use: this must be represented as a string
comprised only of hex digits. If only the key is specified, the
IV must additionally be specified using the -iv option. When
both a key and a password are specified, the key given with the
-K option will be used and the IV generated from the password
will be taken. It probably does not make much sense to specify
both key and password.
-iv IV
The actual IV to use: this must be represented as a string
comprised only of hex digits. When only the key is specified
using the -K option, the IV must explicitly be defined. When a
password is being specified using one of the other options, the
IV is generated from this password.
-md digest
Use the specified digest to create the key from the passphrase.
The default algorithm as of this writing is sha-256. But this
has changed over time. It was md5 in the past. So you might want
to specify this parameter every time to alleviate problems when
moving your encrypted data from one system to another or when
updating openssl to a newer version.
Aunque ha preguntado específicamente sobre OpenSSL, es posible que desee considerar el uso de GPG en su lugar con el propósito de cifrado basado en este artículo OpenSSL vs GPG para cifrar copias de seguridad fuera del sitio.
Para usar GPG para hacer lo mismo, usaría los siguientes comandos:
Encriptar:
gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data
Para descifrar:
gpg --output un_encrypted.data --decrypt encrypted.data
Nota: Se le solicitará una contraseña cuando cifre o descifre.
gpg
me permite descifrar un archivo sin que se me solicite una contraseña. Parece que la contraseña está almacenada durante un período de tiempo, que no quiero.
--no-symkey-cache
deshabilita el almacenamiento en caché al usar gpg con --symmetric
, incluso si el agente se está ejecutando.
Cifrar:
openssl enc -in infile.txt -out encrypted.dat -e -aes256 -k symmetrickey
Descifrar:
openssl enc -in encrypted.dat -out outfile.txt -d -aes256 -k symmetrickey
Para más detalles, ver los openssl(1)
documentos.
-k symmetrickey
con -pass stdin
o-pass 'pass:PASSWORD'
-k symmetrickey
es engañoso. La -k
opción se utiliza para especificar una contraseña, de la cual OpenSSL deriva la clave simétrica. Si desea especificar la clave simétrica, debe usar la -K
opción.
NO UTILICE OPENSSL DEFAULT KEY DERIVATION.
Actualmente, la respuesta aceptada la utiliza y ya no se recomienda ni es segura.
Es muy factible que un atacante simplemente fuerce la llave con fuerza bruta.
https://www.ietf.org/rfc/rfc2898.txt
PBKDF1 aplica una función hash, que será MD2 [6], MD5 [19] o SHA-1 [18], para derivar claves. La longitud de la clave derivada está limitada por la longitud de la salida de la función hash, que es de 16 octetos para MD2 y MD5 y 20 octetos para SHA-1. PBKDF1 es compatible con el proceso de derivación de claves en PKCS # 5 v1.5. PBKDF1 se recomienda solo por compatibilidad con aplicaciones existentes, ya que las claves que produce pueden no ser lo suficientemente grandes para algunas aplicaciones.
PBKDF2 aplica una función pseudoaleatoria (ver Apéndice B.1 para un ejemplo) para derivar claves. La longitud de la clave derivada es esencialmente ilimitada. (Sin embargo, el espacio de búsqueda efectivo máximo para la clave derivada puede estar limitado por la estructura de la función pseudoaleatoria subyacente. Consulte el Apéndice B.1 para una discusión más detallada). Se recomienda PBKDF2 para nuevas aplicaciones.
Hacer esto:
openssl enc -aes-256-cbc -pbkdf2 -iter 20000 -in hello -out hello.enc -k meow
openssl enc -d -aes-256-cbc -pbkdf2 -iter 20000 -in hello.enc -out hello.out
Nota : Las iteraciones en el descifrado deben ser las mismas que las iteraciones en el cifrado.
Las iteraciones tienen que ser un mínimo de 10000. Aquí hay una buena respuesta sobre la cantidad de iteraciones: https://security.stackexchange.com/a/3993
Además ... tenemos suficiente gente aquí recomendando GPG. Lee la maldita pregunta.
Encriptar:
$ openssl bf < arquivo.txt > arquivo.txt.bf
Para descifrar:
$ openssl bf -d < arquivo.txt.bf > arquivo.txt
bf === Blowfish en modo CBC
Actualice utilizando una clave pública generada al azar.
Encypt:
openssl enc -aes-256-cbc -a -salt -in {raw data} -out {encrypted data} -pass file:{random key}
Descifrar:
openssl enc -d -aes-256-cbc -in {ciphered data} -out {raw data}
Tengo un tutorial completo sobre esto en http://bigthinkingapplied.com/key-based-encryption-using-openssl/
Tenga en cuenta que la CLI de OpenSSL utiliza un algoritmo no estándar débil para convertir la frase de contraseña en una clave, y la instalación de resultados de GPG en varios archivos agregados a su directorio de inicio y un proceso de fondo del agente gpg en ejecución. Si desea la máxima portabilidad y control con las herramientas existentes, puede usar PHP o Python para acceder a las API de nivel inferior y pasar directamente una clave AES completa y IV.
Ejemplo de invocación de PHP a través de Bash:
IV='c2FtcGxlLWFlcy1pdjEyMw=='
KEY='Twsn8eh2w2HbVCF5zKArlY+Mv5ZwVyaGlk5QkeoSlmc='
INPUT=123456789023456
ENCRYPTED=$(php -r "print(openssl_encrypt('$INPUT','aes-256-ctr',base64_decode('$KEY'),OPENSSL_ZERO_PADDING,base64_decode('$IV')));")
echo '$ENCRYPTED='$ENCRYPTED
DECRYPTED=$(php -r "print(openssl_decrypt('$ENCRYPTED','aes-256-ctr',base64_decode('$KEY'),OPENSSL_ZERO_PADDING,base64_decode('$IV')));")
echo '$DECRYPTED='$DECRYPTED
Esto produce:
$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456
También puede usar la openssl_pbkdf2
función de PHP para convertir una frase de contraseña en una clave de forma segura.
Hay un programa de código abierto que encuentro en línea que utiliza openssl para cifrar y descifrar archivos. Lo hace con una sola contraseña. Lo mejor de este script de código abierto es que elimina el archivo original sin cifrar al destruir el archivo. Pero lo peligroso es que una vez que el archivo original no encriptado haya desaparecido, debe asegurarse de recordar su contraseña; de lo contrario, no habrá otra forma de descifrar su archivo.
Aquí el enlace está en github
https://github.com/EgbieAnderson1/linux_file_encryptor/blob/master/file_encrypt.py
Como se mencionó en las otras respuestas, las versiones anteriores de openssl usaban una función de derivación de clave débil para derivar una clave de cifrado AES de la contraseña. Sin embargo, openssl v1.1.1 admite una función de derivación de clave más fuerte, donde la clave se deriva de la contraseña utilizandopbkdf2
una sal generada aleatoriamente y múltiples iteraciones de hash sha256 (10,000 por defecto).
Para cifrar un archivo:
openssl aes-256-cbc -e -salt -pbkdf2 -iter 10000 -in plaintextfilename -out encryptedfilename
Para descifrar un archivo:
openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename
Comentarios adicionales a mti2935 buena respuesta.
Parece que a mayor iteración, mejor protección contra la fuerza bruta, y debe usar una iteración alta, ya que puede permitirse el rendimiento / recurso inteligente.
En mi viejo Intel i3-7100 encriptando un archivo bastante grande de 1.5GB:
time openssl enc -aes256 -e -pbkdf2 -iter 10000 -pass pass:"mypassword" -in "InputFile" -out "OutputFile"
Seconds: 2,564s
time openssl enc -aes256 -e -pbkdf2 -iter 262144 -pass pass:"mypassword" -in "InputFile" -out "OutputFile"
Seconds: 2,775s
Realmente no hay ninguna diferencia, aunque no verifiqué el uso de memoria (?)
Con las GPU de hoy, y las mañanas aún más rápidas, creo que mil millones de iteraciones de fuerza bruta parecen posibles cada segundo.
Hace 12 años, a NVIDIA GeForce 8800 Ultra
podía iterar más de 200,000 millones / seg de iteraciones (aunque el hash MD5)
PKCS5_PBKDF2_HMAC
. Debe usar lasEVP_*
funciones para cifrar y descifrar. Vea EVP Symmetric Encryption and Decryption en la wiki de OpenSSL. De hecho, probablemente debería ser autenticado mediante el cifrado, ya que proporciona tanto la confidencialidad y autenticidad. Vea EVP Authenticated Encryption and Decryption en la wiki de OpenSSL.