Jak korzystać z OpenSSL do szyfrowania / deszyfrowania plików?

205

Chcę zaszyfrować i odszyfrować jeden plik za pomocą jednego hasła.

Jak mogę to zrobić za pomocą OpenSSL?

aF.
źródło
2
Należy uzyskać klucz i IV z hasła za pomocą PKCS5_PBKDF2_HMAC. Należy użyć EVP_*funkcji do szyfrowania i deszyfrowania. Zobacz Symetryczne szyfrowanie i deszyfrowanie EVP na wiki OpenSSL. W rzeczywistości prawdopodobnie powinieneś używać uwierzytelnionego szyfrowania, ponieważ zapewnia ono zarówno poufność, jak i autentyczność. Zobacz: Szyfrowanie i deszyfrowanie uwierzytelnione EVP na wiki OpenSSL.
jww
3
Nie rozumiem z twojego pytania, dlaczego chcesz OpenSSL. Poniższy komentarz pokazuje, że GPG jest lepsza - również ze względu na bezpieczeństwo. stackoverflow.com/a/31552829/952234 Głosuję za.
Yaroslav Nikitenko

Odpowiedzi:

261

Ostrzeżenie bezpieczeństwa : AES-256-CBC nie zapewnia uwierzytelnionego szyfrowania i jest podatny na ataki typu padding oracle . Zamiast tego powinieneś użyć czegoś takiego jak wiek .

Szyfruj:

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

Odszyfruj:

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

Więcej informacji na temat różnych flag

Szocske
źródło
18
Odpowiedź prawdopodobnie nie jest optymalna (jak na ten tekst) w zależności od przypadku użycia OP. W szczególności parametry „-a” prawdopodobnie nie są optymalne, a odpowiedź nie wyjaśnia ich zastosowania. „-a” jest zwykle używane, gdy zaszyfrowane dane wyjściowe mają być przesyłane w formacie ASCII / tekstowym i powodują zwiększenie wielkości wyjściowej w porównaniu z formą binarną. Oryginalny plakat nie określa formatu wyjściowego, więc uważam, że przynajmniej należy o tym wspomnieć. Zobacz odpowiedź: stackoverflow.com/a/31552829/952234, która zawiera także uwagę na temat tego, dlaczego do tego zadania należy używać gpg zamiast openssl.
moo
7
Nie używaj powyższego polecenia, ponieważ nie ma pochodnej klucza. Przeczytaj więcej tutaj: wyprowadzenie słabego klucza openssl
jonasl
Należy również podać klucz lub podać, skąd pochodzi. Czy to jest wzmocnione?
Tuntable
2
@jonasl zgodnie z najnowszą stroną podręcznika, stwierdza: „Domyślny skrót został zmieniony z MD5 na SHA256 w openssl 1.1.0.” Źródło: github.com/openssl/openssl/blob/master/doc/man1/enc.pod
Kebman
2
Dodając do komentarza @Kebman, możesz dodać -md sha256do swojego polecenia kodowania i dekodowania, jeśli planujesz używać tego pliku na innym komputerze. To powinno Cię zabezpieczyć przed niezgodnościami / różnicami wersji OpenSSL
dev-rowbot
162

Krótka odpowiedź:

Prawdopodobnie chcesz użyć gpgzamiast tego openssl, patrz „Dodatkowe uwagi” na końcu tej odpowiedzi. Ale aby odpowiedzieć na pytanie, używając openssl:

Aby zaszyfrować:

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

Aby odszyfrować:

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

Uwaga: Podczas szyfrowania lub deszyfrowania pojawi się monit o podanie hasła.


Długa odpowiedź:

Najlepszym źródłem informacji jest openssl encprawdopodobnie: https://www.openssl.org/docs/man1.1.1/man1/enc.html

Wiersz polecenia: openssl enc przyjmuje następującą postać:

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]

Wyjaśnienie najbardziej przydatnych parametrów w odniesieniu do twojego pytania:

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

Dodatkowe uwagi:

Chociaż konkretnie pytałeś o OpenSSL, możesz rozważyć użycie GPG zamiast do szyfrowania na podstawie tego artykułu OpenSSL vs GPG do szyfrowania kopii zapasowych poza witryną?

Aby użyć tego samego GPG, użyj następujących poleceń:

Aby zaszyfrować:

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

Aby odszyfrować:

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

Uwaga: Podczas szyfrowania lub deszyfrowania pojawi się monit o podanie hasła.

muczeć
źródło
8
Świetny komentarz na temat preferowania GPG zamiast OpenSSL. Uważam, że to niesamowite, że OpenSSL używa tak słabego hashowania klucza dla klucza!
Mark
2
Pamiętaj, aby użyć opcji „-md md5” w celu zachowania zgodności z plikami zaszyfrowanymi na starszym openssl bez określonej opcji -md, w przeciwnym razie okaże się, że pliki nie zostaną odszyfrowane w nowszych systemach: github.com/libressl-portable/ portable /
Issues
1
Wartości domyślne zmieniają się między wersjami openssl. 1.0.x używa domyślnej wartości md5 dla opcji -md. Wersja 1.1.x używa sha256. Jeśli odszyfrujesz i pojawi się błąd „: koperta cyfrowa: EVP_DecryptFinal_ex: zły odszyfruj”. spróbuj podać „-md md5” lub „-md sha256”.
txyoji
1
„Podczas szyfrowania lub deszyfrowania pojawi się monit o podanie hasła”. gpgpozwala mi odszyfrować plik bez pytania o hasło. Wygląda na to, że hasło jest przechowywane przez pewien czas, czego nie chcę.
user76284
1
@moo Wydaje się również, że opcja --no-symkey-cachewyłącza buforowanie podczas używania gpg z --symmetric, nawet jeśli agent jest uruchomiony.
user76284
32

Szyfruj:

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

Odszyfruj:

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

Aby uzyskać szczegółowe informacje, zobacz openssl(1)dokumenty.

Ken Cheung
źródło
11
Aby użyć hasła zwykłego tekstu, wymienić -k symmetrickeysię -pass stdinlub-pass 'pass:PASSWORD'
Zenexer
3
Nie używaj powyższego polecenia, ponieważ nie ma pochodnej klucza. Przeczytaj więcej tutaj: wyprowadzenie słabego klucza openssl
jonasl
4
Powiązane z komentarzem @ jonasl, zauważ, że -k symmetrickeyjest to mylące. -kOpcja służy do podawania hasła, z którego wywodzi OpenSSL klucz symetryczny. Jeśli chcesz określić klucz symetryczny, musisz użyć -Kopcji.
user1071847,
13

NIE UŻYWAJ DOMYŚLNEJ POCHODZENIA OPENSSL.

Obecnie zaakceptowana odpowiedź korzysta z niej i nie jest już zalecana ani bezpieczna.

Jest bardzo możliwe, aby atakujący po prostu brutalnie nacisnął klawisz.

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

PBKDF1 stosuje funkcję skrótu, którą jest MD2 [6], MD5 [19] lub SHA-1 [18], w celu uzyskania kluczy. Długość pochodnego klucza jest ograniczona długością wyniku funkcji skrótu, która wynosi 16 oktetów dla MD2 i MD5 i 20 oktetów dla SHA-1. PBKDF1 jest zgodny z procesem wyprowadzania klucza w PKCS # 5 v1.5. PBKDF1 jest zalecany tylko ze względu na kompatybilność z istniejącymi aplikacjami, ponieważ klucze, które produkuje, mogą nie być wystarczająco duże dla niektórych aplikacji.

PBKDF2 stosuje funkcję pseudolosową (patrz przykład w dodatku B.1) w celu uzyskania kluczy. Długość klucza pochodnego jest zasadniczo nieograniczona. (Jednak maksymalna efektywna przestrzeń wyszukiwania dla wyprowadzonego klucza może być ograniczona przez strukturę podstawowej funkcji pseudolosowej. Patrz Dodatek B.1 w celu dalszej dyskusji.) PBKDF2 jest zalecany dla nowych aplikacji.

Zrób to:

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

Uwaga : Iteracje w odszyfrowywaniu muszą być takie same jak iteracje w szyfrowaniu.

Iteracje muszą wynosić co najmniej 10000. Oto dobra odpowiedź na temat liczby iteracji: https://security.stackexchange.com/a/3993

Ponadto ... mamy tutaj wystarczającą liczbę osób, które polecają GPG. Przeczytaj to cholerne pytanie.

Arnold Balliu
źródło
4

Aby zaszyfrować:

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

Aby odszyfrować:

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

bf === Blowfish w trybie CBC

fabio almeida
źródło
3

Zaktualizuj za pomocą losowo wygenerowanego klucza publicznego.

Encypt:

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

Odszyfruj:

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

Mam pełny samouczek na ten temat pod adresem http://bigthinkingapplied.com/key-based-encryption-using-openssl/

nneko
źródło
3

Zauważ, że interfejs OpenSSL CLI używa słabego niestandardowego algorytmu do konwersji hasła na klucz, a instalacja GPG powoduje dodanie różnych plików do katalogu domowego i uruchomienie procesu w tle agenta gpg. Jeśli chcesz mieć maksymalną przenośność i kontrolę przy użyciu istniejących narzędzi, możesz użyć PHP lub Pythona, aby uzyskać dostęp do interfejsów API niższego poziomu i bezpośrednio przekazać pełny klucz AES i IV.

Przykład wywołania PHP przez 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

To daje:

$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456

Możesz także użyć openssl_pbkdf2funkcji PHP, aby bezpiecznie przekonwertować hasło na klucz.

zeroimpl
źródło
Interfejs CLS openssl teraz implementuje i ostrzega użytkowników, że powinni używać PBKDF2 do mieszania haseł. Jednak domyślna liczba iteracji jest bardzo niska i musi być znacznie większa.
Anthony
2

Istnieje program open source, który znajduję online, który używa openssl do szyfrowania i deszyfrowania plików. Robi to za pomocą jednego hasła. Wspaniałą rzeczą w tym skrypcie typu open source jest to, że usuwa on oryginalny nieszyfrowany plik, niszcząc go. Ale niebezpieczną rzeczą jest to, że po zniknięciu oryginalnego niezaszyfrowanego pliku musisz upewnić się, że pamiętasz hasło, w przeciwnym razie nie będzie to żaden inny sposób na odszyfrowanie pliku.

Tutaj link znajduje się na github

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

Michael Linkston
źródło
Rzeczy zmieniły się podczas korzystania z openssl do szyfrowania plików, jest ich o wiele więcej opcji, które należy zapamiętać, aby można było pomyślnie odszyfrować zaszyfrowane pliki. Jednym z rozwiązań tego problemu jest „keepout” antofthy.gitlab.io/software/#keepout
Anthony
2

Jak wspomniano w innych odpowiedziach, poprzednie wersje openssl używały funkcji wyprowadzania słabego klucza do uzyskania klucza szyfrowania AES z hasła. Jednak openssl 1.1.1 obsługuje silniejszą funkcję wyprowadzania klucza, w której klucz jest uzyskiwany z hasła przy użyciu pbkdf2losowo generowanej soli i wielokrotnych iteracji mieszania sha256 (domyślnie 10 000).

Aby zaszyfrować plik:

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

Aby odszyfrować plik:

  openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename
mti2935
źródło
Co w miarę zmieniania się tych opcji oznacza, że ​​musisz także rejestrować, jakie opcje były używane podczas tworzenia każdego zaszyfrowanego pliku openssl. Zwłaszcza, że ​​liczba iteracji powinna rosnąć z czasem! W przypadku jednego rozwiązania zobacz relatywnie proste opakowanie wokół openssl enc ... „keepout” antofthy.gitlab.io/software/#keepout Może się rozwinąć, aby objąć więcej openssl w miarę upływu czasu.
Anthony
@anthony wygląda na użyteczny projekt. Zobacz także github.com/meixler/web-browser-based-file-encryption-decryption
mti2935
0

Dodatkowe komentarze do dobrej odpowiedzi mti2935.

Wydaje się, że im wyższa iteracja, tym lepsza ochrona przed brutalną siłą i powinieneś używać wysokiej iteracji, ponieważ możesz sobie pozwolić na wydajność / zasoby.

Na moim starym Intelie i3-7100 szyfrującym dość duży plik 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

Naprawdę nie ma różnicy, chociaż nie sprawdziłem użycia pamięci (?)

Przy dzisiejszych procesorach graficznych i jeszcze szybszych jutrach wydaje mi się, że miliard iteracji brutalnej siły wydaje się możliwy co sekundę.

12 lat temu NVIDIA GeForce 8800 Ultramożna było iterować ponad 200 000 milionów / s iteracji (choć skrót MD5)

źródło: Ainane-Barrett-Johnson-Vivar-OpenSSL.pdf

MrCalvin
źródło