Як зашифрувати великий файл у openssl за допомогою відкритого ключа


78

Як я можу зашифрувати великий файл за допомогою відкритого ключа, щоб ніхто, крім того, у кого є приватний ключ, не міг його розшифрувати?

Я можу зробити RSA відкритим і закритим ключами, але коли мова заходить про шифрування великого файлу, використовуючи цю команду:

openssl rsautl -encrypt -pubin -inkey public.pem -in myLargeFile.xml -out myLargeFile_encrypted.xml

і як я можу також виконати розшифровку ....

я створюю свій приватний та відкритий ключ за допомогою наступних команд

openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -outform PEM -pubout

Я отримую цю помилку:

RSA operation error
3020:error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size:.\crypto\rsa\rsa_pk1.c:151:

Я намагався зробити ключі розмірами від 1024 до 1200 біт, не пощастило, та сама помилка

Відповіді:


82

Криптографія з відкритим ключем не призначена для шифрування довільно довгих файлів. Для звичайного шифрування використовується симетричний шифр (скажімо, AES). Кожного разу, коли новий випадковий симетричний ключ генерується, використовується та шифрується за допомогою RSA-шифру (відкритого ключа). Шифротекст разом із зашифрованим симетричним ключем передається одержувачу. Одержувач розшифровує симетричний ключ за допомогою свого приватного ключа, а потім використовує симетричний ключ для розшифровки повідомлення.

Приватний ключ ніколи не ділиться, лише відкритий ключ використовується для шифрування випадкового симетричного шифру.


1
Але суть асиметричної криптографії запобігти спільне використання приватної таємниці, цей підхід призводить до обміну ключа , навіть якщо його шифрується асиметричним cryptography.Is яке - або перевага у використанні асиметричної криптографії , як RSA для шифрування загального секрету проти симетричних алгоритмів
техо

3
@techno: ти не ділишся секретами. Ви генеруєте одноразовий випадковий ключ, використовуєте його для шифрування одного повідомлення та викидаєте його. Ключ, який ви надсилаєте разом із повідомленням, дійсний лише для цього повідомлення.
п. 'займенники' m.

1
Так, але одноразовий ключ для конкретного повідомлення ділиться правильно? Чи є якась перевага у використанні асиметричної криптографії, як RSA, для шифрування загальної таємниці проти симетричних алгоритмів
техно

7
Так. Ви також ділитесь самим повідомленням. Якщо ви боїтесь поділитися ключем, також не повідомляйте повідомлення.
п. 'займенники' m.

1
@nm "Криптографічний ключ не призначений для шифрування довільно довгих файлів.", строго з точки зору продуктивності? Використання відкритого ключа одержувача (або того, хто повинен прочитати файл) для RSA-шифрування цілого файлу може мати інші недоліки?
cYrus

73

Рішення для безпечного та надійного кодування будь-якого файлу в OpenSSL та командному рядку:

Ви повинні мати готовий сертифікат X.509 для шифрування файлів у форматі PEM.

Шифрувати файл:

openssl smime -encrypt -binary -aes-256-cbc -in plainfile.zip -out encrypted.zip.enc -outform DER yourSslCertificate.pem

Що є що:

  • smime - команда ssl для утиліти S / MIME ( smime (1) )
  • -encrypt - обраний метод обробки файлів
  • -binary - використовуйте безпечний файл-процес. Зазвичай вхідне повідомлення перетворюється у "канонічний" формат, як вимагає специфікація S / MIME, цей перемикач його відключає. Це необхідно для всіх двійкових файлів (таких як зображення, звуки, архіви ZIP).
  • -aes-256-cbc - вибраний шифр AES у 256 бітах для шифрування (сильний). Якщо не вказано, використовується 40-бітний RC2 (дуже слабкий). ( Підтримувані шифри )
  • -in plainfile.zip - ім'я вхідного файлу
  • -out encrypted.zip.enc - ім'я вихідного файлу
  • -outform DER - кодувати вихідний файл як двійковий. Якщо не вказано, файл кодується base64 і розмір файлу буде збільшено на 30%.
  • yourSslCertificate.pem - ім'я файлу вашого сертифіката. Це має бути у форматі PEM.

Ця команда може дуже ефективно сильно шифрувати великі файли незалежно від їх формату.
Відома проблема: Стається щось не так, коли ви намагаєтесь зашифрувати величезний файл (> 600 МБ). Помилка не видана, але зашифрований файл буде пошкоджено. Завжди перевіряйте кожен файл! (або використовуйте PGP - який має більшу підтримку шифрування файлів із відкритим ключем)

Дешифрувати файл:

openssl smime -decrypt -binary -in encrypted.zip.enc -inform DER -out decrypted.zip -inkey private.key -passin pass:your_password

Що є що:

  • -inform DER - те саме, що -outform вище
  • -inkey private.key - ім'я файлу вашого приватного ключа. Це має бути у форматі PEM і може бути зашифровано за допомогою пароля.
  • -passin pass: your_password - ваш пароль для шифрування приватного ключа. ( аргументи парольної фрази )

1
Коли я виконую наведену вище команду, я отримую a Usage smime [options] yourSslCertificate.pem ...з усіма опціями smime.
Брайан Армстронг

4
Виявилося, мені довелося робити -aes256замість цього-aes-256-cbc
Брайан Армстронг

9
"Ця команда може дуже ефективно сильно зашифрувати будь-який файл, незалежно від його розміру або формату.", Але на жаль, в останньому абзаці ви визнаєте, що він взагалі не може шифрувати великі файли. і всі файли, коли врешті-решт ваше рішення просто не працює для великих файлів. Вам слід починати з обмежень та обсягу вашого рішення, а не закінчувати з ним.
Тимо

2
Чи є повідомлення про помилку щодо цієї відомої проблеми з великими файлами> 600 МБ? Перевірити зашифрований файл неможливо, якщо у вас є лише відкритий ключ.
Сампо

Це небезпечне рішення. Це призводить до ВТРАТИ інформації для великих файлів (> 2 Гб). Спочатку потрібно розділити великий файл
l0pan

30

Ви не можете безпосередньо зашифрувати великий файл за допомогою rsautl. натомість зробіть щось на зразок наступного:

  1. Створіть ключ, використовуючи openssl rand, наприклад,openssl rand 32 -out keyfile
  2. Зашифруйте файл ключа за допомогою openssl rsautl
  3. Зашифруйте дані за openssl encдопомогою згенерованого ключа з кроку 1.
  4. Пакуйте зашифрований файл ключа із зашифрованими даними. одержувачу потрібно буде розшифрувати ключ своїм приватним ключем, а потім розшифрувати дані отриманим ключем.

28

Я знайшов інструкцію на веб- сайті http://www.czeskis.com/random/openssl-encrypt-file.html корисною.

Щоб перефразувати пов’язаний сайт з іменами файлів із вашого прикладу:

Створіть симетричний ключ, оскільки за допомогою нього можна зашифрувати великі файли

openssl rand -base64 32 > key.bin

Зашифруйте великий файл за допомогою симетричного ключа

openssl enc -aes-256-cbc -salt -in myLargeFile.xml \
  -out myLargeFile.xml.enc -pass file:./key.bin

Зашифруйте симетричний ключ, щоб ви могли безпечно надіслати його іншій особі

openssl rsautl -encrypt -inkey public.pem -pubin -in key.bin -out key.bin.enc

Знищте зашифрований симетричний ключ, щоб його ніхто не знайшов

shred -u key.bin

На цьому етапі ви надсилаєте зашифрований симетричний ключ ( key.bin.enc) та зашифрований великий файл ( myLargeFile.xml.enc) іншій особі

Потім інша особа може розшифрувати симетричний ключ за допомогою свого приватного ключа

openssl rsautl -decrypt -inkey private.pem -in key.bin.enc -out key.bin

Тепер вони можуть використовувати симетричний ключ для дешифрування файлу

openssl enc -d -aes-256-cbc -in myLargeFile.xml.enc \
  -out myLargeFile.xml -pass file:./key.bin

І готово. Інша особа має розшифрований файл, і його благополучно надіслано.


1
Це найкраще рішення. Мав бути найвищим рейтингом і прийнятою відповіддю
Кінг

22

Шифрувати дуже великий файл за допомогою smime не рекомендується, оскільки ви можете зашифрувати великі файли за допомогою опції -stream, але не розшифрувати отриманий файл через апаратні обмеження див.

Як вже згадувалося вище, криптографічний ключ не призначений для шифрування довільно довгих файлів. Тому наступні команди згенерують фразу для передачі, зашифрують файл за допомогою симетричного шифрування, а потім зашифрують фразу для передачі за допомогою асиметричного (відкритого ключа). Примітка: smime включає використання первинного відкритого ключа та резервного ключа для шифрування парольної фрази. Резервна пара відкритих / приватних ключів буде розумною.

Генерація випадкових паролів

Встановіть значення RANDFILE у файл, доступний поточному користувачеві, згенеруйте файл passwd.txt та очистіть налаштування

export OLD_RANDFILE=$RANDFILE
RANDFILE=~/rand1
openssl rand -base64 2048 > passwd.txt
rm ~/rand1
export RANDFILE=$OLD_RANDFILE

Шифрування

Використовуйте команди нижче, щоб зашифрувати файл, використовуючи вміст passwd.txt як пароль, а AES256 - до файлу base64 (-a). Зашифруйте passwd.txt за допомогою асиметричного шифрування у файл XXLarge.crypt.pass за допомогою первинного відкритого ключа та резервного ключа.

openssl enc -aes-256-cbc -a -salt -in XXLarge.data -out XXLarge.crypt -pass file:passwd.txt
openssl smime -encrypt -binary -in passwd.txt -out XXLarge.crypt.pass -aes256 PublicKey1.pem PublicBackupKey.pem
rm passwd.txt

Розшифровка

Дешифрування просто розшифровує XXLarge.crypt.pass до passwd.tmp, дешифрує XXLarge.crypt до XXLarge2.data і видаляє файл passwd.tmp.

openssl smime -decrypt -binary -in XXLarge.crypt.pass -out passwd.tmp -aes256 -recip PublicKey1.pem -inkey PublicKey1.key
openssl enc -d -aes-256-cbc -a -in XXLarge.crypt -out XXLarge2.data -pass file:passwd.tmp
rm passwd.tmp

Це тестувалось щодо файлів> 5 ГБ ..

5365295400 Nov 17 10:07 XXLarge.data
7265504220 Nov 17 10:03 XXLarge.crypt
      5673 Nov 17 10:03 XXLarge.crypt.pass
5365295400 Nov 17 10:07 XXLarge2.data

3

Щоб безпечно зашифрувати великі файли (> 600 МБ), openssl smimeвам доведеться розділити кожен файл на невеликі фрагменти:

# Splits large file into 500MB pieces
split -b 500M -d -a 4 INPUT_FILE_NAME input.part.

# Encrypts each piece
find -maxdepth 1 -type f -name 'input.part.*' | sort | xargs -I % openssl smime -encrypt -binary -aes-256-cbc -in % -out %.enc -outform DER PUBLIC_PEM_FILE

Для інформації, ось як розшифрувати та скласти всі частини:

# Decrypts each piece
find -maxdepth 1 -type f -name 'input.part.*.enc' | sort | xargs -I % openssl smime -decrypt -in % -binary -inform DEM -inkey PRIVATE_PEM_FILE -out %.dec

# Puts all together again
find -maxdepth 1 -type f -name 'input.part.*.dec' | sort | xargs cat > RESTORED_FILE_NAME

3

Більш детально пояснивши n. 'pronouns' m.відповідь,

Криптографія з відкритим ключем не призначена для шифрування довільно довгих файлів. Для звичайного шифрування використовується симетричний шифр (скажімо, AES). Кожного разу, коли новий випадковий симетричний ключ генерується, використовується та шифрується за допомогою RSA-шифру (відкритого ключа). Шифротекст разом із зашифрованим симетричним ключем передається одержувачу. Одержувач розшифровує симетричний ключ за допомогою свого приватного ключа, а потім використовує симетричний ключ для розшифровки повідомлення.

Існує потік шифрування :

+---------------------+      +--------------------+
|                     |      |                    |
| generate random key |      |   the large file   |
|        (R)          |      |        (F)         |
|                     |      |                    |
+--------+--------+---+      +----------+---------+
         |        |                     |
         |        +------------------+  |
         |                           |  |
         v                           v  v
+--------+------------+     +--------+--+------------+
|                     |     |                        |
| encrypt (R) with    |     | encrypt (F)            |
| your RSA public key |     | with symmetric key (R) |
|                     |     |                        |
|  ASym(PublicKey, R) |     |     EF = Sym(F, R)     |
|                     |     |                        |
+----------+----------+     +------------+-----------+
           |                             |
           +------------+ +--------------+
                        | |
                        v v
         +--------------+-+---------------+
         |                                |
         |   send this files to the peer  |
         |                                |
         |     ASym(PublicKey, R) + EF    |
         |                                |
         +--------------------------------+

І потік розшифровки :

   +----------------+        +--------------------+
   |                |        |                    |
   | EF = Sym(F, R) |        | ASym(PublicKey, R) |
   |                |        |                    |
   +-----+----------+        +---------+----------+
         |                             |
         |                             |
         |                             v
         |   +-------------------------+-----------------+
         |   |                                           |
         |   |             restore key (R)               |
         |   |                                           |
         |   | R <= ASym(PrivateKey, ASym(PublicKey, R)) |
         |   |                                           |
         |   +---------------------+---------------------+
         |                         |
         v                         v
     +---+-------------------------+---+
     |                                 |
     |       restore the file (F)      |
     |                                 |
     |      F <= Sym(Sym(F, R), R)     |
     |                                 |
     +---------------------------------+

Крім того, ви можете використовувати ці команди:

# generate random symmetric key
openssl rand -base64 32 > /config/key.bin

# encryption
openssl rsautl -encrypt -pubin -inkey /config/public_key.pem -in /config/key.bin -out /config/key.bin.enc
openssl aes-256-cbc -a -pbkdf2 -salt -in  $file_name -out $file_name.enc -k $(cat /config/key.bin)

# now you can send this files: $file_name.enc + /config/key.bin.enc

# decryption
openssl rsautl -decrypt -inkey /config/private_key.pem -in /config/key.bin.enc -out /config/key.bin
openssl aes-256-cbc -d -a -in $file_name.enc -out $file_name -k $(cat /config/key.bin)

2

Можливо, вам слід перевірити прийняту відповідь на це запитання ( Як зашифрувати дані у php за допомогою відкритих / приватних ключів? ).

Замість того, щоб вручну обходити обмеження розміру повідомлення (або, можливо, риси) RSA, воно показує, як використовувати функцію S / mime OpenSSL для того, щоб робити те саме, і не потрібно жонглювати симетричним ключем вручну.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.