Come usare OpenSSL per crittografare / decrittografare i file?


205

Voglio crittografare e decrittografare un file usando una password.

Come posso usare OpenSSL per farlo?


2
È necessario derivare una chiave e IV dalla password utilizzando PKCS5_PBKDF2_HMAC. È necessario utilizzare le EVP_*funzioni per crittografare e decrittografare. Vedi EVP Symmetric Encryption and Decryption sul wiki OpenSSL. In effetti, dovresti probabilmente utilizzare la crittografia autenticata perché fornisce sia riservatezza che autenticità. Vedi EVP Authenticated Encryption and Decryption sul wiki OpenSSL.
jww

3
Non capisco dalla tua domanda perché vuoi OpenSSL. Un commento qui sotto mostra che GPG è migliore, anche a causa della sicurezza. stackoverflow.com/a/31552829/952234 voto in basso.
Yaroslav Nikitenko

Risposte:


261

Avviso di sicurezza : AES-256-CBC non fornisce la crittografia autenticata ed è vulnerabile agli attacchi di imbottitura dell'oracolo . Dovresti usare qualcosa come l' età .

Encrypt:

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

Decrypt:

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

Maggiori dettagli sulle varie bandiere


18
Probabilmente la risposta non è ottimale (al momento della stesura di questo documento) a seconda del caso d'uso dell'OP. In particolare, i parametri "-a" probabilmente non sono ottimali e la risposta non spiega il suo utilizzo. "-a" viene in genere utilizzato quando l'output crittografato deve essere trasmesso in formato ASCII / testo e ha l'effetto di aumentare le dimensioni dell'output rispetto al formato binario. Il poster originale non specifica il formato di output e quindi penso che almeno questo dovrebbe essere menzionato. Vedi risposta: stackoverflow.com/a/31552829/952234 che include anche una nota sul perché dovresti usare gpg invece di openssl per questa attività.
moo,

7
Non utilizzare il comando sopra poiché non esiste una derivazione della chiave. Leggi di più qui: openssl derivazione chiave debole
jonasl

Dovrebbe anche specificare una chiave o menzionare la sua provenienza. È rafforzato?
Montabile

2
@jonasl secondo l'ultima pagina man, afferma: "Il digest predefinito è stato cambiato da MD5 a SHA256 in Openssl 1.1.0." Fonte: github.com/openssl/openssl/blob/master/doc/man1/enc.pod
Kebman

2
Aggiungendo al commento di @Kebman, è possibile aggiungere -md sha256al comando di codifica e decodifica se si prevede di utilizzare questo file su un altro computer. Ciò dovrebbe
coprirti dalle

162

Risposta breve:

Probabilmente vuoi usare gpginvece di opensslcosì vedi "Note aggiuntive" alla fine di questa risposta. Ma per rispondere alla domanda usando openssl:

Per crittografare:

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

Per decifrare:

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

Nota: ti verrà richiesta una password durante la crittografia o la decrittografia.


Risposta lunga:

La tua migliore fonte di informazioni per openssl encprobabilmente sarebbe: https://www.openssl.org/docs/man1.1.1/man1/enc.html

Riga di comando: openssl enc assume la forma seguente:

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]

Spiegazione dei parametri più utili per quanto riguarda la tua domanda:

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

Note aggiuntive:

Sebbene tu abbia chiesto specificamente di OpenSSL, potresti prendere in considerazione l'utilizzo di GPG invece ai fini della crittografia basata su questo articolo OpenSSL vs GPG per la crittografia dei backup off-site?

Per usare GPG per fare lo stesso dovresti usare i seguenti comandi:

Per crittografare:

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

Per decifrare:

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

Nota: ti verrà richiesta una password durante la crittografia o la decrittografia.


8
Ottimo commento sulla preferenza per GPG su OpenSSL. Trovo incredibile che OpenSSL utilizzi un hash derivato da password così debole per la chiave!
Segna il

2
Assicurati di usare l'opzione "-md md5" per la compatibilità con i file che sono stati crittografati su openssl precedente senza l'opzione -md specificata, altrimenti scoprirai che i file non verranno decifrati sui sistemi più recenti: github.com/libressl-portable/ portabile / numeri / 378
Sam Liddicott,

1
I valori predefiniti cambiano tra le versioni di openssl. 1.0.x utilizza un valore predefinito di md5 per l'opzione -md. La versione 1.1.x utilizza sha256. Se decifri e ricevi un errore ": routine di inviluppo digitale: EVP_DecryptFinal_ex: decodifica errata". prova a specificare "-md md5" o "-md sha256".
Txyoji,

1
"Ti verrà richiesta una password durante la crittografia o la decrittografia." gpgmi consente di decrittografare un file senza che sia richiesta una password. Sembra che la password sia memorizzata per un certo periodo di tempo, che non voglio.
user76284

1
@moo Sembra anche che l'opzione --no-symkey-cachedisabiliti la memorizzazione nella cache quando si utilizza gpg con --symmetric, anche se l'agente è in esecuzione.
user76284

32

Encrypt:

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

Decrypt:

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

Per i dettagli, consultare i openssl(1)documenti.


11
Per usare una password in chiaro, sostituisci -k symmetrickeycon -pass stdino-pass 'pass:PASSWORD'
Zenexer il

3
Non utilizzare il comando sopra poiché non esiste una derivazione della chiave. Leggi di più qui: openssl derivazione chiave debole
jonasl

4
In relazione al commento di @Jonasl, nota che -k symmetrickeyè fuorviante. L' -kopzione viene utilizzata per specificare una password, da cui OpenSSL deriva la chiave simmetrica. Se si desidera specificare la chiave simmetrica, è necessario utilizzare l' -Kopzione
user1071847

13

NON UTILIZZARE LA DERIVAZIONE CHIAVE DEFAULT OPENSSL.

Attualmente la risposta accettata la utilizza e non è più consigliata e sicura.

È molto fattibile per un attaccante semplicemente forzare la chiave.

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

PBKDF1 applica una funzione hash, che deve essere MD2 [6], MD5 [19] o SHA-1 [18], per derivare le chiavi. La lunghezza della chiave derivata è limitata dalla lunghezza dell'uscita della funzione hash, che è di 16 ottetti per MD2 e MD5 e 20 ottetti per SHA-1. PBKDF1 è compatibile con il processo di derivazione delle chiavi in ​​PKCS # 5 v1.5. PBKDF1 è consigliato solo per la compatibilità con le applicazioni esistenti poiché le chiavi che produce potrebbero non essere sufficientemente grandi per alcune applicazioni.

PBKDF2 applica una funzione pseudocasuale (vedere l'Appendice B.1 per un esempio) per derivare i tasti. La lunghezza della chiave derivata è sostanzialmente illimitata. (Tuttavia, lo spazio di ricerca massimo effettivo per la chiave derivata può essere limitato dalla struttura della funzione pseudocasuale sottostante. Vedere l'Appendice B.1 per ulteriori discussioni.) PBKDF2 è raccomandato per le nuove applicazioni.

Fai questo:

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 : le iterazioni nella decrittografia devono essere le stesse delle iterazioni nella crittografia.

Le iterazioni devono essere almeno di 10000. Ecco una buona risposta sul numero di iterazioni: https://security.stackexchange.com/a/3993

Inoltre ... qui ci sono abbastanza persone che raccomandano GPG. Leggi la dannata domanda.


4

Per crittografare:

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

Per decifrare:

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

bf === Blowfish in modalità CBC



3

Si noti che la CLI OpenSSL utilizza un algoritmo non standard debole per convertire la passphrase in una chiave e l'installazione dei risultati GPG in vari file aggiunti alla directory home e un processo in background di gpg-agent in esecuzione. Se desideri la massima portabilità e controllo con gli strumenti esistenti, puoi utilizzare PHP o Python per accedere alle API di livello inferiore e passare direttamente una chiave AES completa e IV.

Esempio di invocazione PHP tramite 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

Questo produce:

$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456

Puoi anche usare la openssl_pbkdf2funzione di PHP per convertire una passphrase in una chiave in modo sicuro.


La CLI di Openssl ora implementa e avverte gli utenti che dovrebbero usare PBKDF2 per l'hash della password. Tuttavia, il conteggio delle iterazioni predefinite è molto basso e deve essere molto più grande.
Anthony

2

C'è un programma open source che trovo online che utilizza openssl per crittografare e decrittografare i file. Lo fa con una sola password. La cosa grandiosa di questo script open source è che elimina il file originale non crittografato distruggendo il file. Ma la cosa pericolosa è che una volta che il file originale non crittografato è sparito, devi assicurarti di ricordare la tua password, altrimenti non saranno altri modi per decifrare il tuo file.

Qui il link è su github

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


Le cose sono cambiate quando si utilizza openssl per la crittografia dei file, ci sono molte più opzioni, che devono essere ricordate per poter decifrare con successo i file crittografati. Una soluzione a questo è "keepout" antofthy.gitlab.io/software/#keepout
anthony

2

Come menzionato nelle altre risposte, le versioni precedenti di openssl utilizzavano una funzione di derivazione della chiave debole per derivare una chiave di crittografia AES dalla password. Tuttavia, openssl v1.1.1 supporta una funzione di derivazione della chiave più potente, in cui la chiave viene derivata dalla password mediantepbkdf2 con un salt generato in modo casuale e più iterazioni di hashing sha256 (10.000 per impostazione predefinita).

Per crittografare un file:

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

Per decrittografare un file:

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

Il che, man mano che queste opzioni continuano a cambiare, significa che è necessario anche tenere traccia di quali opzioni sono state utilizzate durante la creazione di ciascun file crittografato openssl. Soprattutto perché il conteggio delle iterazioni dovrebbe aumentare con il tempo! Per una soluzione vedere come un wrapper relativamente semplice intorno a openssl enc ... "keepout" antofthy.gitlab.io/software/#keepout Può espandersi per includere più openssl col passare del tempo.
Anthony

@anthony sembra un progetto utile. Vedi anche github.com/meixler/web-browser-based-file-encryption-decryption
mti2935

0

Ulteriori commenti a mti2935 buona risposta.

Sembra che la più alta iterazione sia la migliore protezione contro la forza bruta e dovresti usare una iterazione elevata in quanto puoi permetterti prestazioni / risorse sagge.

Sul mio vecchio Intel i3-7100 crittografando un file piuttosto grande da 1,5 GB:

 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

Nessuna differenza, non ho verificato l'utilizzo della memoria (?)

Con le GPU di oggi e domani ancora più veloci, immagino che miliardi di iterazioni a forza bruta sembrino possibili ogni secondo.

12 anni fa aNVIDIA GeForce 8800 Ultra possibile iterare oltre 200.000 milioni / sec iterazioni (hashing MD5)

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.