Làm cách nào để sử dụng OpenSSL để mã hóa / giải mã tập tin?


205

Tôi muốn mã hóa và giải mã một tập tin bằng một mật khẩu.

Làm thế nào tôi có thể sử dụng OpenSSL để làm điều đó?


2
Bạn nên lấy Khóa và IV từ mật khẩu bằng cách sử dụng PKCS5_PBKDF2_HMAC. Bạn nên sử dụng các EVP_*chức năng để mã hóa và giải mã. Xem Mã hóa và giải mã đối xứng EVP trên wiki OpenSSL. Trên thực tế, có lẽ bạn nên sử dụng mã hóa được xác thực bởi vì nó cung cấp cả tính bảo mật và tính xác thực. Xem Mã hóa và giải mã được chứng thực EVP trên wiki OpenSSL.
21:30

3
Không hiểu từ câu hỏi của bạn tại sao bạn muốn OpenSSL. Một bình luận dưới đây cho thấy GPG tốt hơn - cũng vì bảo mật. stackoverflow.com/a/31552829/952234 Tôi bỏ phiếu xuống.
Yaroslav Nikitenko

Câu trả lời:


261

Cảnh báo bảo mật : AES-256-CBC không cung cấp mã hóa được xác thực và dễ bị tấn công bởi các cuộc tấn công sấm sét . Bạn nên sử dụng một cái gì đó như tuổi thay thế.

Mã hóa:

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

Giải mã:

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

Thêm chi tiết về các cờ khác nhau


18
Câu trả lời có thể không tối ưu (như cách viết này) tùy thuộc vào trường hợp sử dụng của OP. Cụ thể, các tham số "-a" có thể không tối ưu và câu trả lời không giải thích việc sử dụng nó. "-a" thường được sử dụng khi đầu ra được mã hóa được truyền ở dạng ASCII / văn bản và có tác dụng tăng kích thước đầu ra so với dạng nhị phân. Các poster ban đầu không chỉ định định dạng đầu ra và vì vậy tôi cảm thấy rằng ít nhất điều này nên được đề cập. Xem câu trả lời: stackoverflow.com/a/31552829/952234 cũng bao gồm một lưu ý về lý do tại sao bạn nên sử dụng gpg thay vì openssl cho nhiệm vụ này.
moo

7
Không sử dụng lệnh trên vì không có đạo hàm chính. Đọc thêm tại đây: phái sinh khóa yếu openssl
jonasl

Cũng nên chỉ định một khóa, hoặc đề cập đến nó đến từ đâu. Có phải nó được tăng cường?
Tuntable

2
@jonasl theo trang người đàn ông mới nhất, nó ghi rõ: Triệu Thông báo mặc định đã được thay đổi từ MD5 thành SHA256 trong Openssl 1.1.0. Nguồn: github.com/openssl/openssl/blob/master/doc/man1/enc.pod
Kebman

2
Thêm vào nhận xét từ @Kebman, bạn có thể thêm -md sha256vào lệnh mã hóa và giải mã nếu bạn định sử dụng tệp này trên máy khác. Điều đó sẽ giúp bạn chống lại sự không tương thích / khác biệt của phiên bản OpenSSL
dev-rowbot

162

Câu trả lời ngắn:

Bạn có thể muốn sử dụng gpgthay vì opensslvậy hãy xem "Ghi chú bổ sung" ở cuối câu trả lời này. Nhưng để trả lời câu hỏi bằng cách sử dụng openssl:

Để mã hóa:

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

Để giải mã:

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

Lưu ý: Bạn sẽ được nhắc nhập mật khẩu khi mã hóa hoặc giải mã.


Câu trả lời dài:

Nguồn thông tin tốt nhất của bạn openssl enccó lẽ sẽ là: https://www.openssl.org/docs/man1.1.1/man1/enc.html

Dòng lệnh: openssl enc có dạng sau:

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]

Giải thích về các tham số hữu ích nhất liên quan đến câu hỏi của bạn:

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

Ghi chú bổ sung:

Mặc dù bạn đã hỏi cụ thể về OpenSSL, bạn có thể muốn xem xét sử dụng GPG thay vì mục đích mã hóa dựa trên bài viết này OpenSSL so với GPG để mã hóa sao lưu ngoài trang web?

Để sử dụng GPG để làm tương tự, bạn sẽ sử dụng các lệnh sau:

Để mã hóa:

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

Để giải mã:

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

Lưu ý: Bạn sẽ được nhắc nhập mật khẩu khi mã hóa hoặc giải mã.


8
Nhận xét tuyệt vời về việc thích GPG hơn OpenSSL. Tôi thấy không thể tin được rằng OpenSSL sử dụng hàm băm có mật khẩu yếu như vậy cho khóa!
Đánh dấu

2
Hãy chắc chắn sử dụng tùy chọn "-md md5" để tương thích với các tệp được mã hóa trên openssl cũ mà không có tùy chọn -md được chỉ định, nếu không bạn sẽ thấy rằng các tệp sẽ không giải mã được trên các hệ thống mới hơn: github.com/libressl-portable/ xách tay / vấn đề / 378
Sam Liddicott 18/07/18

1
Giá trị mặc định thay đổi giữa các phiên bản openssl. 1.0.x sử dụng mặc định md5 cho tùy chọn -md. Phiên bản 1.1.x sử dụng sha256. Nếu bạn giải mã và gặp lỗi ": thói quen phong bì kỹ thuật số: EVP_DecryptFinal_ex: giải mã xấu". hãy thử chỉ định "-md md5" hoặc "-md sha256".
txyoji

1
"Bạn sẽ được nhắc nhập mật khẩu khi mã hóa hoặc giải mã." gpgđang cho phép tôi giải mã một tập tin mà không được nhắc nhập mật khẩu. Có vẻ như mật khẩu được lưu trữ trong một khoảng thời gian mà tôi không muốn.
dùng76284

1
@moo Dường như tùy chọn --no-symkey-cachevô hiệu hóa bộ đệm ẩn khi sử dụng gpg với --symmetric, ngay cả khi tác nhân đang chạy.
dùng76284

32

Mã hóa:

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

Giải mã:

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

Để biết chi tiết, xem các openssl(1)tài liệu.


11
Để sử dụng mật khẩu văn bản gốc, thay thế -k symmetrickeybằng -pass stdinhoặc-pass 'pass:PASSWORD'
Zenexer

3
Không sử dụng lệnh trên vì không có đạo hàm chính. Đọc thêm tại đây: mở khóa phái sinh yếu
jonasl

4
Liên quan đến bình luận của @ jonasl, lưu ý đó -k symmetrickeylà sai lệch. Các -ktùy chọn được sử dụng để xác định một mật khẩu, từ đó xuất phát OpenSSL chìa khóa đối xứng. Nếu bạn muốn chỉ định khóa đối xứng, bạn phải sử dụng -Ktùy chọn.
dùng1071847

13

KHÔNG SỬ DỤNG KHAI THÁC KHAI THÁC CHÍNH CỦA OPENSSL.

Hiện tại câu trả lời được chấp nhận sử dụng nó và nó không còn được khuyến nghị và bảo mật.

Nó rất khả thi đối với một kẻ tấn công chỉ đơn giản là vũ phu dùng chìa khóa.

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

PBKDF1 áp dụng hàm băm, sẽ là MD2 [6], MD5 [19] hoặc SHA-1 [18], để lấy các khóa. Độ dài của khóa dẫn xuất được giới hạn bởi độ dài của đầu ra hàm băm, là 16 octet cho MD2 và MD5 và 20 octet cho SHA-1. PBKDF1 tương thích với quy trình phái sinh chính trong PKCS # 5 v1.5. PBKDF1 chỉ được khuyến nghị để tương thích với các ứng dụng hiện có vì các khóa mà nó tạo ra có thể không đủ lớn cho một số ứng dụng.

PBKDF2 áp dụng hàm giả ngẫu nhiên (xem Phụ lục B.1 chẳng hạn) để lấy các khóa. Độ dài của khóa dẫn xuất về cơ bản là không giới hạn. (Tuy nhiên, không gian tìm kiếm hiệu quả tối đa cho khóa dẫn xuất có thể bị giới hạn bởi cấu trúc của chức năng giả ngẫu nhiên cơ bản. Xem Phụ lục B.1 để thảo luận thêm.) PBKDF2 được khuyến nghị cho các ứng dụng mới.

Làm cái này:

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

Ghi chú : Lặp lại trong giải mã phải giống như các lần lặp trong mã hóa.

Lặp lại phải có tối thiểu 10000. Đây là một câu trả lời tốt về số lần lặp: https://security.stackexchange.com/a/3993

Ngoài ra ... chúng tôi đã có đủ người ở đây giới thiệu GPG. Đọc câu hỏi chết tiệt.


4

Để mã hóa:

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

Để giải mã:

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

bf === Cá kiếm ở chế độ CBC


3

Cập nhật bằng khóa công khai được tạo ngẫu nhiên.

Mã hóa:

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

Giải mã:

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

Tôi có một hướng dẫn đầy đủ về điều này tại http://bigthinkingapplied.com/key-basing-encoding-USE-openssl/


3

Lưu ý rằng OpenSSL CLI sử dụng thuật toán không chuẩn yếu để chuyển đổi cụm mật khẩu thành khóa và cài đặt kết quả GPG trong các tệp khác nhau được thêm vào thư mục chính của bạn và quá trình chạy nền của tác nhân gpg đang chạy. Nếu bạn muốn tính di động và kiểm soát tối đa với các công cụ hiện có, bạn có thể sử dụng PHP hoặc Python để truy cập các API cấp thấp hơn và trực tiếp chuyển vào Khóa AES và IV đầy đủ.

Ví dụ lời gọi PHP qua 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

Kết quả này:

$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456

Bạn cũng có thể sử dụng openssl_pbkdf2chức năng của PHP để chuyển đổi cụm mật khẩu thành khóa một cách an toàn.


Openssl CLI hiện thực hiện và cảnh báo người dùng rằng họ nên sử dụng PBKDF2 để băm mật khẩu. Tuy nhiên, số lần lặp mặc định của nó là rất thấp và cần phải lớn hơn nhiều.
anthony

2

Có một chương trình mã nguồn mở mà tôi tìm thấy trực tuyến, nó sử dụng openssl để mã hóa và giải mã tập tin. Nó thực hiện điều này với một mật khẩu duy nhất. Điều tuyệt vời về tập lệnh mã nguồn mở này là nó xóa tệp không được mã hóa ban đầu bằng cách băm nhỏ tệp. Nhưng điều nguy hiểm là khi tệp không được mã hóa ban đầu biến mất, bạn phải đảm bảo rằng bạn nhớ mật khẩu của mình nếu không chúng không còn cách nào khác để giải mã tệp của bạn.

Đây là liên kết trên github

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


Mọi thứ đã thay đổi khi sử dụng openssl để mã hóa tập tin, chúng là nhiều tùy chọn hơn, cần phải được ghi nhớ để bạn có thể giải mã thành công các tệp được mã hóa. Một giải pháp cho vấn đề này là "keepout" antofthy.gitlab.io/software/#keepout
anthony

2

Như đã đề cập trong các câu trả lời khác, các phiên bản trước của openssl đã sử dụng chức năng phái sinh khóa yếu để lấy khóa mã hóa AES từ mật khẩu. Tuy nhiên, openssl v1.1.1 hỗ trợ chức năng phái sinh khóa mạnh hơn, trong đó khóa được lấy từ mật khẩu sử dụng pbkdf2với một muối được tạo ngẫu nhiên và nhiều lần lặp băm sha256 (10.000 theo mặc định).

Để mã hóa một tập tin:

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

Để giải mã một tập tin:

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

Khi các tùy chọn này tiếp tục thay đổi, có nghĩa là bạn cũng cần phải ghi lại những tùy chọn đã được sử dụng khi tạo từng tệp được mã hóa openssl. Đặc biệt là số lần lặp sẽ tăng theo thời gian! Đối với một giải pháp, hãy xem như trình bao bọc tương đối đơn giản xung quanh openssl enc ... "keepout" antofthy.gitlab.io/software/#keepout Nó có thể mở rộng để bao gồm nhiều openssl hơn nữa.
anthony

@anthony trông giống như một dự án hữu ích. Đồng thời xem github.com/meixler/web-browser-basing-file-encoding-decoding
mti2935

0

Nhận xét bổ sung cho mti2935 câu trả lời tốt.

Có vẻ như phép lặp càng cao thì khả năng bảo vệ chống lại lực lượng vũ phu càng cao và bạn nên sử dụng số lần lặp cao vì bạn có thể đủ khả năng thực hiện / tài nguyên một cách khôn ngoan.

Trên Intel i3-7100 cũ của tôi, mã hóa một tệp khá lớn 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

Không thực sự khác biệt, mặc dù đã không kiểm tra việc sử dụng bộ nhớ (?)

Với GPU ngày nay, và thậm chí ngày mai nhanh hơn, tôi đoán rằng hàng tỷ lần lặp lại vũ phu dường như có thể mỗi giây.

12 năm trước, số NVIDIA GeForce 8800 Ultralần lặp có thể lặp lại hơn 200.000 triệu / giây (mặc dù băm MD5)

nguồn: Ainane-Barrett-Johnson-Vivar-OpenSSL.pdf

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.