จะใช้ OpenSSL ในการเข้ารหัส / ถอดรหัสไฟล์ได้อย่างไร?


205

ฉันต้องการเข้ารหัสและถอดรหัสไฟล์หนึ่งไฟล์โดยใช้รหัสผ่านเดียว

ฉันจะใช้ OpenSSL เพื่อทำสิ่งนั้นได้อย่างไร


2
คุณควรจะได้รับมาที่สำคัญและ IV PKCS5_PBKDF2_HMACจากรหัสผ่านโดยใช้ คุณควรใช้EVP_*ฟังก์ชั่นในการเข้ารหัสและถอดรหัส ดูEVP Symmetric Encryption and Decryptionบน OpenSSL wiki ในความเป็นจริงคุณควรใช้การเข้ารหัสที่ผ่านการรับรองความถูกต้องเพราะมีทั้งการรักษาความลับและความถูกต้อง ดูการเข้ารหัสและการถอดรหัส EVP ที่รับรองความถูกต้องบนวิกิ OpenSSL
jww

3
ไม่เข้าใจคำถามของคุณว่าทำไมคุณถึงต้องการ OpenSSL ความคิดเห็นด้านล่างแสดงว่า GPG นั้นดีกว่า - เนื่องจากความปลอดภัย stackoverflow.com/a/31552829/952234ฉันลงคะแนน
Yaroslav Nikitenko

คำตอบ:


261

คำเตือนเกี่ยวกับความปลอดภัย : AES-256-CBC ไม่ได้ให้การเข้ารหัสที่รับรองความถูกต้องและมีความเสี่ยงต่อการโจมตีของช่องว่างภายใน คุณควรใช้บางสิ่งบางอย่างเช่นอายุแทน

การเข้ารหัสลับ:

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

ถอดรหัส:

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

รายละเอียดเพิ่มเติมเกี่ยวกับธงต่าง ๆ


18
คำตอบน่าจะไม่ดีที่สุด (ณ การเขียนนี้) ขึ้นอยู่กับกรณีการใช้งานของ OP โดยเฉพาะพารามิเตอร์ "-a" อาจไม่เหมาะสมและคำตอบไม่ได้อธิบายการใช้งาน "-a" มักใช้เมื่อเอาต์พุตที่เข้ารหัสถูกส่งในรูปแบบ ASCII / ข้อความและมีผลต่อการเพิ่มขนาดเอาต์พุตเมื่อเปรียบเทียบกับรูปแบบไบนารี โปสเตอร์ดั้งเดิมไม่ได้ระบุรูปแบบผลลัพธ์ดังนั้นฉันรู้สึกว่าอย่างน้อยที่สุดสิ่งนี้ควรได้รับการกล่าวถึง ดูคำตอบ: stackoverflow.com/a/31552829/952234ซึ่งมีหมายเหตุว่าทำไมคุณควรใช้ gpg แทนที่จะเป็น openssl สำหรับงานนี้
หมู่

7
อย่าใช้คำสั่งข้างต้นเนื่องจากไม่มีการสืบทอดคีย์ อ่านเพิ่มเติมได้ที่นี่: openssl การได้รับคีย์ที่อ่อนแอ
jonasl

ควรระบุรหัสหรือระบุว่ามาจากที่ใด มันแข็งแกร่งขึ้นหรือไม่
ทำได้

2
@ jonasl ตามหน้า man ล่าสุดนั้นระบุ:“ การแยกย่อยเริ่มต้นเปลี่ยนจาก MD5 เป็น SHA256 ใน Openssl 1.1.0” ที่มา: github.com/openssl/openssl/blob/master/doc/man1/enc.pod
Kebman

2
การเพิ่มความคิดเห็นจาก @Kebman คุณสามารถเพิ่ม-md sha256การเข้ารหัสและคำสั่งถอดรหัสถ้าคุณวางแผนที่จะใช้ไฟล์นี้ในเครื่องอื่น ที่ควรจะครอบคลุมคุณจากความเข้ากันไม่ได้ / ความแตกต่างของ OpenSSL เวอร์ชัน
dev-rowbot

162

คำตอบสั้น ๆ :

คุณอาจต้องการใช้gpgแทนopensslเพื่อดู"หมายเหตุเพิ่มเติม"ในตอนท้ายของคำตอบนี้ แต่เพื่อตอบคำถามโดยใช้openssl:

ในการเข้ารหัส:

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

ในการถอดรหัส:

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

หมายเหตุ: คุณจะถูกถามให้ใส่รหัสผ่านเมื่อทำการเข้ารหัสหรือถอดรหัส


คำตอบยาว:

แหล่งข้อมูลที่ดีที่สุดของคุณopenssl encน่าจะเป็น: https://www.openssl.org/docs/man1.1.1/man1/enc.html

บรรทัดคำสั่ง: openssl encใช้แบบฟอร์มต่อไปนี้:

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]

คำอธิบายของพารามิเตอร์ที่มีประโยชน์ที่สุดสำหรับคำถามของคุณ:

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

หมายเหตุเพิ่มเติม:

แม้ว่าคุณได้ถามเกี่ยวกับ OpenSSL โดยเฉพาะคุณอาจต้องการพิจารณาใช้ GPG แทนจุดประสงค์ในการเข้ารหัสตามบทความนี้OpenSSL กับ GPG สำหรับการเข้ารหัสการสำรองข้อมูลนอกสถานที่?

ในการใช้ GPG ให้ทำเช่นเดียวกันคุณจะใช้คำสั่งต่อไปนี้:

ในการเข้ารหัส:

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

ในการถอดรหัส:

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

หมายเหตุ: คุณจะถูกถามให้ใส่รหัสผ่านเมื่อทำการเข้ารหัสหรือถอดรหัส


8
ความคิดเห็นที่ดีเกี่ยวกับการเลือก GPG ผ่าน OpenSSL ฉันคิดว่ามันเหลือเชื่อที่ OpenSSL ใช้แฮชของรหัสผ่านที่อ่อนเช่นรหัส!
ทำเครื่องหมาย

2
อย่าลืมใช้ตัวเลือก "-md md5" เพื่อความเข้ากันได้กับไฟล์ที่เข้ารหัสบน openssl รุ่นเก่าโดยไม่ระบุตัวเลือก -md มิฉะนั้นคุณจะพบว่าไฟล์จะไม่ถอดรหัสในระบบที่ใหม่กว่า: github.com/libressl-portable/ พกพา / ฉบับ / 378
Sam Liddicott

1
ค่าเริ่มต้นจะเปลี่ยนระหว่างรุ่นของ openssl 1.0.x ใช้ค่าเริ่มต้นของ md5 สำหรับตัวเลือก -md เวอร์ชัน 1.1.x ใช้ sha256 หากคุณถอดรหัสและรับข้อผิดพลาด ": ซองจดหมายดิจิทัล: EVP_DecryptFinal_ex: bad decrypt" ข้อผิดพลาด ลองระบุ "-md md5" หรือ "-md sha256"
txyoji

1
"คุณจะได้รับพร้อมท์ให้ใส่รหัสผ่านเมื่อทำการเข้ารหัสหรือถอดรหัส" gpgให้ฉันถอดรหัสไฟล์โดยไม่ต้องใส่รหัสผ่าน ดูเหมือนว่ารหัสผ่านจะถูกเก็บไว้เป็นระยะเวลาหนึ่งซึ่งฉันไม่ต้องการ
user76284

1
@moo ดูเหมือนว่าตัวเลือก--no-symkey-cacheจะปิดใช้งานการแคชเมื่อใช้ gpg ด้วย--symmetricแม้ว่าเอเจนต์จะทำงานอยู่
user76284

32

การเข้ารหัสลับ:

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

ถอดรหัส:

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

สำหรับรายละเอียดโปรดดูopenssl(1)เอกสาร


11
หากต้องการใช้รหัสผ่านแบบธรรมดาให้แทนที่-k symmetrickeyด้วย-pass stdinหรือ-pass 'pass:PASSWORD'
Zenexer

3
อย่าใช้คำสั่งข้างต้นเนื่องจากไม่มีการสืบทอดคีย์ อ่านเพิ่มเติมได้ที่นี่: openssl การได้รับคีย์ที่อ่อนแอ
jonasl

4
เกี่ยวข้องกับความคิดเห็นของ @ jonasl โปรดทราบว่า-k symmetrickeyมีการเข้าใจผิด -kตัวเลือกที่ถูกนำมาใช้สำหรับการระบุรหัสผ่านจากการที่ OpenSSL มาคีย์สมมาตร หากคุณต้องการระบุคีย์สมมาตรคุณต้องใช้-Kตัวเลือก
user1071847

13

ห้ามใช้คำสั่งการเปิดคีย์ DEENSULT

ปัจจุบันคำตอบที่ยอมรับใช้ประโยชน์จากมันและไม่แนะนำและปลอดภัยอีกต่อไป

มันเป็นไปได้มากที่ผู้โจมตีจะใช้กำลังดุร้าย

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

PBKDF1 ใช้ฟังก์ชันแฮชซึ่งจะต้องเป็น MD2 [6], MD5 [19] หรือ SHA-1 [18] เพื่อรับคีย์ ความยาวของคีย์ที่ได้รับนั้นล้อมรอบด้วยความยาวของเอาต์พุตฟังก์ชันแฮชซึ่งคือ 16 octets สำหรับ MD2 และ MD5 และ 20 octets สำหรับ SHA-1 PBKDF1 เข้ากันได้กับกระบวนการรับกุญแจใน PKCS # 5 v1.5 PBKDF1 แนะนำสำหรับความเข้ากันได้กับแอปพลิเคชันที่มีอยู่เท่านั้นเนื่องจากปุ่มที่สร้างขึ้นอาจไม่ใหญ่พอสำหรับแอปพลิเคชั่นบางตัว

PBKDF2 ใช้ฟังก์ชัน pseudorandom (ดูตัวอย่างภาคผนวก B.1) เพื่อรับคีย์ ความยาวของคีย์ที่ได้รับนั้นไม่มีขอบเขต จำกัด (อย่างไรก็ตามพื้นที่ค้นหาที่มีประสิทธิภาพสูงสุดสำหรับคีย์ที่ได้รับอาจถูก จำกัด โดยโครงสร้างของฟังก์ชันหลอกเทียมพื้นฐานดูภาคผนวก B.1 สำหรับการอภิปรายเพิ่มเติม) แนะนำให้ใช้ PBKDF2 สำหรับแอปพลิเคชันใหม่

ทำเช่นนี้:

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

หมายเหตุ : การวนซ้ำในการถอดรหัสจะต้องเหมือนกับการวนซ้ำในการเข้ารหัส

การซ้ำต้องมีอย่างน้อย 10,000 นี่คือคำตอบที่ดีเกี่ยวกับจำนวนการวนซ้ำ: https://security.stackexchange.com/a/3993

นอกจากนี้ ... เรามีคนจำนวนมากพอที่จะแนะนำ GPG อ่านคำถามแช่ง


4

ในการเข้ารหัส:

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

ในการถอดรหัส:

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

bf === ปักเป้าในโหมด CBC


3

อัปเดตโดยใช้กุญแจสาธารณะที่สร้างแบบสุ่ม

Encypt:

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

ถอดรหัส:

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

ฉันมีการสอนเต็มรูปแบบเกี่ยวกับเรื่องนี้ที่http://bigthinkingapplied.com/key-based-encrypt-using-openssl/


3

โปรดทราบว่า OpenSSL CLI ใช้อัลกอริทึมที่ไม่ได้มาตรฐานแบบอ่อนเพื่อแปลงข้อความรหัสผ่านเป็นคีย์และการติดตั้งผลลัพธ์ GPG ในไฟล์ต่างๆที่เพิ่มในโฮมไดเร็กตอรี่ของคุณและกระบวนการพื้นหลัง gpg-agent ทำงาน หากคุณต้องการความสะดวกในการพกพาและการควบคุมสูงสุดด้วยเครื่องมือที่มีอยู่คุณสามารถใช้ PHP หรือ Python เพื่อเข้าถึง API ระดับล่างและส่งผ่านโดยตรงใน AES Key และ IV

ตัวอย่างการเรียกใช้ PHP ผ่าน 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

ผลลัพธ์นี้:

$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456

คุณสามารถใช้openssl_pbkdf2ฟังก์ชั่นของ PHP ในการแปลงข้อความรหัสผ่านเป็นคีย์ได้อย่างปลอดภัย


ตอนนี้ Openssl CLI ใช้และเตือนผู้ใช้ว่าพวกเขาควรใช้ PBKDF2 สำหรับการแฮชรหัสผ่าน อย่างไรก็ตามจำนวนการวนซ้ำเริ่มต้นของมันนั้นต่ำมากและจำเป็นต้องมีขนาดใหญ่กว่ามาก
anthony

2

มีโปรแกรมโอเพนซอร์ซที่ฉันค้นหาออนไลน์มันใช้ openssl เพื่อเข้ารหัสและถอดรหัสไฟล์ มันทำได้ด้วยรหัสผ่านเดียว สิ่งที่ยอดเยี่ยมเกี่ยวกับสคริปต์โอเพนซอร์ซนี้คือการลบไฟล์ที่ไม่ได้เข้ารหัสดั้งเดิมโดยการทำลายไฟล์ แต่สิ่งที่อันตรายคือเมื่อไฟล์ที่ไม่มีการเข้ารหัสดั้งเดิมหายไปคุณต้องแน่ใจว่าคุณจำรหัสผ่านไม่เช่นนั้นจะไม่มีวิธีอื่นในการถอดรหัสไฟล์ของคุณ

ที่นี่ลิงค์มันอยู่ใน GitHub

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


สิ่งต่าง ๆ มีการเปลี่ยนแปลงเมื่อใช้ openssl สำหรับการเข้ารหัสไฟล์ตัวเลือกเพิ่มเติมมีมากมายซึ่งจำเป็นต้องจดจำเพื่อให้คุณสามารถถอดรหัสไฟล์ที่เข้ารหัสได้สำเร็จ วิธีแก้ปัญหานี้คือ "keepout" antofthy.gitlab.io/software/#keepout
anthony

2

ตามที่กล่าวไว้ในคำตอบอื่น ๆ openssl รุ่นก่อนหน้านี้ใช้ฟังก์ชั่นคีย์ที่ได้รับมาอย่างอ่อนเพื่อรับคีย์การเข้ารหัส AES จากรหัสผ่าน อย่างไรก็ตาม openssl v1.1.1 รองรับฟังก์ชั่นการหากุญแจที่แข็งแกร่งกว่าซึ่งกุญแจนั้นได้มาจากรหัสผ่านที่ใช้pbkdf2กับเกลือที่สร้างขึ้นแบบสุ่มและการทำซ้ำหลายครั้งของการแฮช sha256 (10,000 โดยค่าเริ่มต้น)

ในการเข้ารหัสไฟล์:

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

ในการถอดรหัสไฟล์:

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

ซึ่งตัวเลือกเหล่านี้มีการเปลี่ยนแปลงอยู่ตลอดเวลาหมายความว่าคุณต้องเก็บบันทึกตัวเลือกที่ใช้เมื่อสร้างไฟล์ที่เข้ารหัสของ openssl แต่ละไฟล์ โดยเฉพาะอย่างยิ่งเมื่อจำนวนการทำซ้ำควรเพิ่มขึ้นตามเวลา! สำหรับวิธีการแก้ปัญหาหนึ่งให้ดูเป็นเสื้อคลุมที่ค่อนข้างง่าย ๆ รอบ openssl enc ... "keepout" antofthy.gitlab.io/software/#keepout มันสามารถขยายเพื่อรวม openssl เพิ่มเติมได้ตามเวลา
anthony

@anthony ดูเหมือนว่าโครงการที่มีประโยชน์ ดูgithub.com/meixler/web-browser-based-file-encrypt-decryption
mti2935

0

ความคิดเห็นเพิ่มเติมเพื่อ mti2935 คำตอบที่ดี

ดูเหมือนว่าการทำซ้ำที่สูงกว่าการป้องกันที่ดีขึ้นต่อกำลังดุร้ายและคุณควรใช้การทำซ้ำที่สูงเนื่องจากคุณสามารถจ่ายประสิทธิภาพ / ทรัพยากรได้อย่างชาญฉลาด

ใน Intel i3-7100 รุ่นเก่าของฉันกำลังเข้ารหัสไฟล์ขนาดค่อนข้างใหญ่ 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

ไม่แตกต่างกันมากตรวจสอบการใช้หน่วยความจำ (())

ด้วย GPU ในปัจจุบันและในวันพรุ่งนี้ที่เร็วกว่านี้ฉันคิดว่าการวนซ้ำของแรงเดรัจฉานนับพันล้านดูเหมือนเป็นไปได้ทุกวินาที

12ปีที่แล้วNVIDIA GeForce 8800 Ultraสามารถทำซ้ำได้มากกว่า 200,000 ครั้ง / วินาที (MD5 hashing แม้ว่า)

แหล่งที่มา: Ainane-Barrett-Johnson-Vivar-OpenSSL.pdf

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.