Comment utiliser OpenSSL pour crypter / décrypter des fichiers?

205

Je veux crypter et décrypter un fichier en utilisant un seul mot de passe.

Comment puis-je utiliser OpenSSL pour cela?

un F.
la source
2
Vous devez dériver une clé et un IV du mot de passe en utilisant PKCS5_PBKDF2_HMAC. Vous devez utiliser les EVP_*fonctions pour crypter et décrypter. Voir EVP Symmetric Encryption and Decryption sur le wiki OpenSSL. En fait, vous devriez probablement utiliser un cryptage authentifié car il offre à la fois la confidentialité et l'authenticité. Voir Cryptage et décryptage authentifiés EVP sur le wiki OpenSSL.
2015 à 21h28
3
Je ne comprends pas pourquoi vous voulez OpenSSL. Un commentaire ci-dessous montre que GPG est meilleur - également à cause de la sécurité. stackoverflow.com/a/31552829/952234 Je vote contre.
Yaroslav Nikitenko

Réponses:

261

Avertissement de sécurité : AES-256-CBC ne fournit pas de chiffrement authentifié et est vulnérable aux bourrages d'attaques oracle . Vous devriez plutôt utiliser quelque chose comme l' âge .

Crypter:

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

Déchiffrer:

openssl aes-256-cbc -d -a -in secrets.txt.enc -out secrets.txt.new

Plus de détails sur les différents drapeaux

Szocske
la source
18
La réponse n'est probablement pas optimale (au moment de la rédaction de ce document) selon le cas d'utilisation de l'OP. Plus précisément, le paramètre "-a" n'est probablement pas optimal et la réponse n'explique pas son utilisation. "-a" est généralement utilisé lorsque la sortie chiffrée doit être transmise sous forme ASCII / texte et a pour effet d'augmenter la taille de sortie par rapport à la forme binaire. L'affiche originale ne précise pas le format de sortie et je pense donc qu'au moins cela doit être mentionné. Voir la réponse: stackoverflow.com/a/31552829/952234 qui comprend également une note expliquant pourquoi vous devez utiliser gpg au lieu de openssl pour cette tâche.
moo
7
N'utilisez pas la commande ci-dessus car il n'y a pas de dérivation de clé. Lire la suite ici: dérivation de clé faible openssl
jonasl
Doit également spécifier une clé, ou mentionner d'où elle vient. Est-il renforcé?
Tuntable
2
@jonasl selon la dernière page de manuel, il indique: "Le résumé par défaut a été changé de MD5 à SHA256 dans Openssl 1.1.0." Source: github.com/openssl/openssl/blob/master/doc/man1/enc.pod
Kebman
2
En ajoutant au commentaire de @Kebman, vous pouvez ajouter -md sha256à votre commande d'encodage et de décodage si vous prévoyez d'utiliser ce fichier sur une autre machine. Cela devrait vous couvrir contre les incompatibilités / différences de version d'OpenSSL
dev-rowbot
162

Réponse courte:

Vous voudrez probablement utiliser à la gpgplace de openssldonc consultez "Notes supplémentaires" à la fin de cette réponse. Mais pour répondre à la question en utilisant openssl:

Pour crypter:

openssl enc -aes-256-cbc -in un_encrypted.data -out encrypted.data

Pour décrypter:

openssl enc -d -aes-256-cbc -in encrypted.data -out un_encrypted.data

Remarque: Un mot de passe vous sera demandé lors du chiffrement ou du déchiffrement.


Longue réponse:

Votre meilleure source d'informations pour openssl encserait probablement: https://www.openssl.org/docs/man1.1.1/man1/enc.html

Ligne de commande: openssl enc prend la forme suivante:

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]

Explication des paramètres les plus utiles par rapport à votre question:

-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.

Notes complémentaires:

Bien que vous ayez spécifiquement posé des questions sur OpenSSL, vous voudrez peut-être envisager d'utiliser plutôt GPG à des fins de chiffrement sur la base de cet article OpenSSL vs GPG pour chiffrer les sauvegardes hors site?

Pour utiliser GPG pour faire de même, vous utiliseriez les commandes suivantes:

Pour crypter:

gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data

Pour décrypter:

gpg --output un_encrypted.data --decrypt encrypted.data

Remarque: Un mot de passe vous sera demandé lors du chiffrement ou du déchiffrement.

meuglement
la source
8
Grand commentaire sur la préférence de GPG sur OpenSSL. Je trouve incroyable qu'OpenSSL utilise un hachage dérivé de mot de passe aussi faible pour la clé!
Mark
2
Assurez-vous d'utiliser l'option "-md md5" pour la compatibilité avec les fichiers qui ont été chiffrés sur les versions antérieures d'OpenSL sans l'option -md spécifiée, sinon vous constaterez que les fichiers ne seront pas déchiffrés sur les systèmes plus récents: github.com/libressl-portable/ portable / issues / 378
Sam Liddicott
1
Les valeurs par défaut changent entre les versions de openssl. 1.0.x utilise une valeur par défaut de md5 pour l'option -md. La version 1.1.x utilise sha256. Si vous déchiffrez et obtenez une erreur ": routines d'enveloppe numérique: EVP_DecryptFinal_ex: mauvais déchiffrement". essayez de spécifier "-md md5" ou "-md sha256".
txyoji
1
"Vous serez invité à entrer un mot de passe lors du cryptage ou du décryptage." gpgme permet de décrypter un fichier sans être invité à saisir un mot de passe. Il semble que le mot de passe soit stocké pendant une certaine période de temps, ce que je ne veux pas.
user76284
1
@moo Il semble également que l'option --no-symkey-cachedésactive la mise en cache lors de l'utilisation de gpg avec --symmetric, même si l'agent est en cours d'exécution.
user76284
32

Crypter:

openssl enc -in infile.txt -out encrypted.dat -e -aes256 -k symmetrickey

Déchiffrer:

openssl enc -in encrypted.dat -out outfile.txt -d -aes256 -k symmetrickey

Pour plus de détails, consultez la openssl(1)documentation.

Ken Cheung
la source
11
Pour utiliser un mot de passe en clair, remplacez-le -k symmetrickeypar -pass stdinou-pass 'pass:PASSWORD'
Zenexer
3
N'utilisez pas la commande ci-dessus car il n'y a pas de dérivation de clé. Lire la suite ici: dérivation de clé faible openssl
jonasl
4
Relatif au commentaire de @ jonasl, notez que cela -k symmetrickeyest trompeur. L' -koption est utilisée pour spécifier un mot de passe, dont OpenSSL dérive la clé symétrique. Si vous souhaitez spécifier la clé symétrique, vous devez utiliser l' -Koption.
user1071847
13

N'UTILISEZ PAS LA DÉRIVATION DE CLÉ PAR DÉFAUT D'OPENSSL.

Actuellement, la réponse acceptée en fait usage et elle n'est plus recommandée et sécurisée.

Il est très possible pour un attaquant de simplement forcer brutalement la clé.

https://www.ietf.org/rfc/rfc2898.txt

PBKDF1 applique une fonction de hachage, qui doit être MD2 [6], MD5 [19] ou SHA-1 [18], pour dériver les clés. La longueur de la clé dérivée est limitée par la longueur de la sortie de la fonction de hachage, qui est de 16 octets pour MD2 et MD5 et de 20 octets pour SHA-1. PBKDF1 est compatible avec le processus de dérivation de clé dans PKCS # 5 v1.5. PBKDF1 est recommandé uniquement pour la compatibilité avec les applications existantes, car les clés qu'il produit peuvent ne pas être suffisamment grandes pour certaines applications.

PBKDF2 applique une fonction pseudo-aléatoire (voir l'annexe B.1 pour un exemple) pour dériver des clés. La longueur de la clé dérivée est essentiellement illimitée. (Cependant, l'espace de recherche effectif maximal pour la clé dérivée peut être limité par la structure de la fonction pseudo-aléatoire sous-jacente. Voir l'Annexe B.1 pour plus de détails.) PBKDF2 est recommandé pour les nouvelles applications.

Faites ceci:

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

Remarque : les itérations de décryptage doivent être les mêmes que les itérations de cryptage.

Les itérations doivent être au minimum de 10000. Voici une bonne réponse sur le nombre d'itérations: https://security.stackexchange.com/a/3993

De plus ... nous avons suffisamment de personnes ici recommandant GPG. Lisez la fichue question.

Arnold Balliu
la source
4

Pour crypter:

$ openssl bf < arquivo.txt > arquivo.txt.bf

Pour décrypter:

$ openssl bf -d < arquivo.txt.bf > arquivo.txt

bf === Blowfish en mode CBC

fabio almeida
la source
3

Mettre à jour à l'aide d'une clé publique générée au hasard.

Encypt:

openssl enc -aes-256-cbc -a -salt -in {raw data} -out {encrypted data} -pass file:{random key}

Déchiffrer:

openssl enc -d -aes-256-cbc -in {ciphered data} -out {raw data}

J'ai un tutoriel complet à ce sujet sur http://bigthinkingapplied.com/key-based-encryption-using-openssl/

nneko
la source
3

Notez que l'OpenSSL CLI utilise un algorithme non standard faible pour convertir la phrase secrète en une clé, et l'installation des résultats GPG dans divers fichiers ajoutés à votre répertoire personnel et un processus d'arrière-plan de l'agent gpg en cours d'exécution. Si vous souhaitez une portabilité et un contrôle maximum avec les outils existants, vous pouvez utiliser PHP ou Python pour accéder aux API de niveau inférieur et transmettre directement une clé AES complète et IV.

Exemple d'invocation PHP via 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

Cela produit:

$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456

Vous pouvez également utiliser la openssl_pbkdf2fonction PHP pour convertir une phrase secrète en clé en toute sécurité.

zeroimpl
la source
Openssl CLI implémente désormais et avertit les utilisateurs qu'ils doivent utiliser PBKDF2 pour le hachage de mot de passe. Cependant, son nombre d'itérations par défaut est très faible et doit être beaucoup plus grand.
Anthony
2

Il y a un programme open source que je trouve en ligne, il utilise openssl pour crypter et décrypter des fichiers. Il le fait avec un seul mot de passe. La grande chose à propos de ce script open source est qu'il supprime le fichier non chiffré d'origine en déchiquetant le fichier. Mais la chose dangereuse est qu'une fois que le fichier original non crypté a disparu, vous devez vous assurer de vous souvenir de votre mot de passe, sinon ils ne pourront pas décrypter votre fichier autrement.

Voici le lien c'est sur github

https://github.com/EgbieAnderson1/linux_file_encryptor/blob/master/file_encrypt.py

Michael linkston
la source
Les choses ont changé lorsque vous utilisez openssl pour le cryptage de fichiers, ce sont beaucoup plus d'options, qui doivent être mémorisées pour que vous puissiez décrypter avec succès les fichiers cryptés. Une solution à cela est "keepout" antofthy.gitlab.io/software/#keepout
anthony
2

Comme mentionné dans les autres réponses, les versions précédentes d'OpenSL utilisaient une fonction de dérivation de clé faible pour dériver une clé de chiffrement AES à partir du mot de passe. Cependant, openssl v1.1.1 prend en charge une fonction de dérivation de clé plus puissante, où la clé est dérivée du mot de passe à l'aide pbkdf2d'un sel généré de manière aléatoire, et plusieurs itérations de hachage sha256 (10 000 par défaut).

Pour crypter un fichier:

 openssl aes-256-cbc -e -salt -pbkdf2 -iter 10000 -in plaintextfilename -out encryptedfilename

Pour décrypter un fichier:

  openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename
mti2935
la source
Ce qui, comme ces options ne cessent de changer, signifie que vous devez également garder une trace des options qui ont été utilisées lors de la création de chaque fichier crypté openssl. D'autant plus que le nombre d'itérations devrait augmenter avec le temps! Pour une solution, voyez comme un wrapper relativement simple autour de openssl enc ... "keepout" antofthy.gitlab.io/software/#keepout Il peut s'étendre pour inclure plus openssl au fil du temps.
anthony
@anthony ressemble à un projet utile. Voir également github.com/meixler/web-browser-based-file-encryption-decryption
mti2935
0

Commentaires supplémentaires à mti2935 bonne réponse.

Il semble que plus l'itération est élevée, meilleure est la protection contre la force brute, et vous devriez utiliser une itération élevée car vous pouvez vous permettre des performances / ressources.

Sur mon mon ancien Intel i3-7100 chiffrant un fichier assez gros de 1,5 Go:

 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

Pas vraiment de différence, mais je n'ai pas vérifié l'utilisation de la mémoire (?)

Avec les GPU d'aujourd'hui et des lendemains encore plus rapides, je suppose que des milliards d'itérations en force brute semblent possibles toutes les secondes.

Il y a 12 ans, une NVIDIA GeForce 8800 Ultraitération de plus de 200 000 millions d'itérations par seconde (hachage MD5)

source: Ainane-Barrett-Johnson-Vivar-OpenSSL.pdf

MrCalvin
la source