Bagaimana cara menggunakan OpenSSL untuk mengenkripsi / mendekripsi file?

205

Saya ingin crypt dan mendekripsi satu file menggunakan satu kata sandi.

Bagaimana saya bisa menggunakan OpenSSL untuk melakukan itu?

aF.
sumber
2
Anda harus mendapatkan Kunci dan IV dari kata sandi menggunakan PKCS5_PBKDF2_HMAC. Anda harus menggunakan EVP_*fungsi untuk mengenkripsi dan mendekripsi. Lihat Enkripsi dan Dekripsi Simetri EVP pada wiki OpenSSL. Bahkan, Anda mungkin harus menggunakan enkripsi dikonfirmasi karena memberikan baik kerahasiaan dan keaslian. Lihat Enkripsi dan Dekripsi terotentikasi EVP pada wiki OpenSSL.
jww
3
Tidak mengerti dari pertanyaan Anda mengapa Anda menginginkan OpenSSL. Sebuah komentar di bawah ini menunjukkan GPG lebih baik - juga karena keamanan. stackoverflow.com/a/31552829/952234 Saya pilih.
Yaroslav Nikitenko

Jawaban:

261

Peringatan Keamanan : AES-256-CBC tidak menyediakan enkripsi yang diautentikasi dan rentan terhadap serangan oracle . Anda harus menggunakan sesuatu seperti usia sebagai gantinya.

Enkripsi:

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

Dekripsi:

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

Lebih detail tentang berbagai bendera

Szocske
sumber
18
Jawabannya kemungkinan tidak optimal (pada penulisan ini) tergantung pada use case OP. Secara khusus parameter "-a" kemungkinan tidak optimal dan jawabannya tidak menjelaskan penggunaannya. "-a" biasanya digunakan ketika output terenkripsi akan dikirimkan dalam bentuk ASCII / teks dan memiliki efek meningkatkan ukuran output dibandingkan bentuk biner. Poster asli tidak menentukan format output dan jadi saya merasa bahwa paling tidak ini harus disebutkan. Lihat jawaban: stackoverflow.com/a/31552829/952234 yang juga menyertakan catatan tentang mengapa Anda harus menggunakan gpg alih-alih openssl untuk tugas ini.
moo
7
Jangan gunakan perintah di atas karena tidak ada penurunan kunci. Baca lebih lanjut di sini: derivasi kunci openssl lemah
jonasl
Harus juga menentukan kunci, atau menyebutkan dari mana asalnya. Apakah ini diperkuat?
Tuntable
2
@jonasl menurut halaman manual terbaru, menyatakan: "Intisari default diubah dari MD5 ke SHA256 di Openssl 1.1.0." Sumber: github.com/openssl/openssl/blob/master/doc/man1/enc.pod
Kebman
2
Menambahkan ke komentar dari @ Tebman, Anda dapat menambahkan -md sha256perintah encode dan decode Anda jika Anda berencana menggunakan file ini di komputer lain. Itu seharusnya melindungi Anda dari ketidaksesuaian / perbedaan versi OpenSSL
dev-rowbot
162

Jawaban singkat:

Anda mungkin ingin menggunakan gpgdaripada opensslmelihat "Catatan Tambahan" di akhir jawaban ini. Tetapi untuk menjawab pertanyaan menggunakan openssl:

Untuk Mengenkripsi:

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

Untuk Mendekripsi:

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

Catatan: Anda akan dimintai kata sandi saat mengenkripsi atau mendekripsi.


Jawaban panjang:

Sumber informasi terbaik Anda openssl encmungkin adalah: https://www.openssl.org/docs/man1.1.1/man1/enc.html

Baris perintah: openssl enc mengambil bentuk berikut:

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]

Penjelasan parameter paling berguna sehubungan dengan pertanyaan Anda:

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

Catatan tambahan:

Meskipun Anda secara khusus bertanya tentang OpenSSL, Anda mungkin ingin mempertimbangkan untuk menggunakan GPG sebagai ganti enkripsi berdasarkan artikel ini OpenSSL vs GPG untuk mengenkripsi cadangan di luar situs?

Untuk menggunakan GPG untuk melakukan hal yang sama Anda akan menggunakan perintah berikut:

Untuk Mengenkripsi:

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

Untuk Mendekripsi:

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

Catatan: Anda akan dimintai kata sandi saat mengenkripsi atau mendekripsi.

melenguh
sumber
8
Komentar hebat tentang lebih memilih GPG daripada OpenSSL. Saya merasa luar biasa bahwa OpenSSL menggunakan hash turunan kata sandi yang lemah untuk kuncinya!
Markus
2
Pastikan untuk menggunakan opsi "-md md5" untuk kompatibilitas dengan file yang dienkripsi pada openssl lama tanpa opsi -md ditentukan, jika tidak, Anda akan menemukan bahwa file tidak akan mendekripsi pada sistem yang lebih baru: github.com/libressl-portable/ portable / issues / 378
Sam Liddicott
1
Nilai default berubah antara versi openssl. 1.0.x menggunakan default md5 untuk opsi -md. Versi 1.1.x menggunakan sha256. Jika Anda mendekripsi dan mendapatkan kesalahan ": amplop digital: EVP_DecryptFinal_ex: kesalahan dekripsi buruk". coba sebutkan "-md md5" atau "-md sha256".
txyoji
1
"Anda akan dimintai kata sandi saat mengenkripsi atau mendekripsi." gpgmembiarkan saya mendekripsi file tanpa diminta kata sandi. Sepertinya kata sandi disimpan untuk jangka waktu tertentu, yang tidak saya inginkan.
user76284
1
@moo Tampaknya juga opsi --no-symkey-cachemenonaktifkan caching saat menggunakan gpg --symmetric, bahkan jika agen sedang berjalan.
user76284
32

Enkripsi:

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

Dekripsi:

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

Untuk detailnya, lihat openssl(1)dokumen.

Ken Cheung
sumber
11
Untuk menggunakan kata sandi teks biasa, ganti -k symmetrickeydengan -pass stdinatau-pass 'pass:PASSWORD'
Zenexer
3
Jangan gunakan perintah di atas karena tidak ada penurunan kunci. Baca lebih lanjut di sini: derivasi kunci openssl lemah
jonasl
4
Terkait dengan komentar @ jonasl, perhatikan bahwa -k symmetrickeyitu menyesatkan. The -kopsi digunakan untuk menentukan password, dari mana OpenSSL berasal kunci simetrik. Jika Anda ingin menentukan kunci simetris, Anda harus menggunakan -Kopsi.
user1071847
13

JANGAN GUNAKAN DERIVASI KUNCI OPENSSL DEFAULT.

Saat ini jawaban yang diterima memanfaatkannya dan tidak lagi direkomendasikan dan aman.

Sangat mungkin bagi seorang penyerang untuk secara kasar memaksa kunci.

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

PBKDF1 menerapkan fungsi hash, yang harus MD2 [6], MD5 [19] atau SHA-1 [18], untuk mendapatkan kunci. Panjang kunci yang diturunkan dibatasi oleh panjang output fungsi hash, yaitu 16 oktet untuk MD2 dan MD5 dan 20 oktet untuk SHA-1. PBKDF1 kompatibel dengan proses derivasi kunci dalam PKCS # 5 v1.5. PBKDF1 hanya direkomendasikan untuk kompatibilitas dengan aplikasi yang ada karena tombol yang dihasilkannya mungkin tidak cukup besar untuk beberapa aplikasi.

PBKDF2 menerapkan fungsi pseudorandom (lihat Lampiran B.1 untuk contoh) untuk mendapatkan kunci. Panjang kunci yang diturunkan pada dasarnya tidak terbatas. (Namun, ruang pencarian efektif maksimum untuk kunci yang diturunkan mungkin dibatasi oleh struktur fungsi pseudorandom yang mendasarinya. Lihat Lampiran B.1 untuk diskusi lebih lanjut.) PBKDF2 direkomendasikan untuk aplikasi baru.

Melakukan hal ini:

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

Catatan : Iterasi dalam dekripsi harus sama dengan iterasi dalam enkripsi.

Iterasi harus minimal 10.000. Berikut ini adalah jawaban yang bagus tentang jumlah iterasi: https://security.stackexchange.com/a/3993

Juga ... kita punya cukup banyak orang di sini merekomendasikan GPG. Baca pertanyaannya.

Arnold Balliu
sumber
4

Untuk Mengenkripsi:

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

Untuk Mendekripsi:

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

bf === Blowfish dalam mode CBC

fabio almeida
sumber
3

Perbarui menggunakan kunci publik yang dibuat secara acak.

Encypt:

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

Dekripsi:

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

Saya memiliki tutorial lengkap tentang ini di http://bigthinkingapplied.com/key-based-encryption-using-openssl/

nneko
sumber
3

Perhatikan bahwa OpenSSL CLI menggunakan algoritma non-standar yang lemah untuk mengubah frasa sandi menjadi kunci, dan menginstal hasil GPG dalam berbagai file yang ditambahkan ke direktori home Anda dan proses latar belakang agen gpg berjalan. Jika Anda ingin portabilitas dan kontrol maksimum dengan alat yang ada, Anda dapat menggunakan PHP atau Python untuk mengakses API tingkat lebih rendah dan langsung memasukkan Kunci AES dan IV penuh.

Contoh permohonan PHP melalui 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

Output ini:

$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456

Anda juga bisa menggunakan openssl_pbkdf2fungsi PHP untuk mengonversi kata sandi menjadi kunci dengan aman.

nolimpl
sumber
Opensl CLI sekarang mengimplementasikan dan memperingatkan pengguna bahwa mereka harus menggunakan PBKDF2 untuk hashing kata sandi. Namun jumlah iterasi standarnya sangat rendah, dan harus jauh lebih besar.
anthony
2

Ada program open source yang saya temukan online menggunakan openssl untuk mengenkripsi dan mendekripsi file. Ini dilakukan dengan satu kata sandi. Hal yang hebat tentang skrip open source ini adalah ia menghapus file asli yang tidak dienkripsi dengan merobek-robek file. Tetapi hal yang berbahaya tentang adalah begitu file asli yang tidak terenkripsi hilang, Anda harus memastikan Anda mengingat kata sandi Anda jika tidak mereka tidak akan bisa mendekripsi file Anda.

Di sini tautannya ada di github

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

Michael linkston
sumber
Banyak hal telah berubah ketika menggunakan openssl untuk enkripsi file, mereka adalah lebih banyak opsi, yang perlu diingat agar Anda dapat berhasil mendekripsi file yang dienkripsi. Salah satu solusi untuk ini adalah "keepout" antofthy.gitlab.io/software/#keepout
anthony
2

Seperti disebutkan dalam jawaban lain, versi openssl sebelumnya menggunakan fungsi derivasi kunci yang lemah untuk memperoleh kunci enkripsi AES dari kata sandi. Namun, openssl v1.1.1 mendukung fungsi derivasi kunci yang lebih kuat, di mana kunci tersebut berasal dari kata sandi yang digunakan pbkdf2dengan garam yang dibuat secara acak, dan beberapa iterasi hashing sha256 (10.000 secara default).

Untuk mengenkripsi file:

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

Untuk mendekripsi file:

  openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename
mti2935
sumber
Yang mana karena opsi-opsi ini terus berubah, berarti Anda perlu juga mencatat opsi apa yang digunakan saat membuat setiap file yang dienkripsi openssl. Terutama karena jumlah iterasi akan meningkat seiring waktu! Untuk satu solusi lihat sebagai pembungkus yang relatif sederhana di sekitar ... "keepout" antofthy.gitlab.io/software/#keepout Ini dapat diperluas untuk memasukkan lebih banyak openssl saat waktu terus berjalan.
anthony
@anthony terlihat seperti proyek yang bermanfaat. Lihat juga github.com/meixler/web-browser-based-file-encryption-decryption
mti2935
0

Komentar tambahan untuk mti2935 jawaban yang bagus.

Tampaknya semakin tinggi iterasi maka perlindungan yang lebih baik terhadap brute force, dan Anda harus menggunakan iterasi yang tinggi karena Anda mampu dengan kinerja / sumber daya yang bijaksana.

Pada Intel i3-7100 lama saya mengenkripsi file yang agak besar 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

Tidak ada bedanya, tidak memeriksa penggunaan memori (?)

Dengan GPU hari ini, dan bahkan hari esok yang lebih cepat, saya kira miliar iterasi kasar tampaknya mungkin setiap detik.

12 tahun yang lalu NVIDIA GeForce 8800 Ultrabisa mengulangi lebih dari 200.000 juta / detik iterasi (MD5 hashing)

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

Tuan Calvin
sumber