Вопрос или проблема
Я генерирую приватный зашифрованный ключ RSA:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key_enc_private.pem -aes256
Затем извлекаю публичный ключ RSA:
openssl rsa -pubout -in key_enc_private.pem -out key_public.pem
Используя публичный ключ, я шифрую один файл:
openssl enc -aes-256-cbc -salt -pbkdf2 -in open.txt -out open_encrypted.txt -pass file:key_public.pem
Для того чтобы расшифровать файл open_encrypted.txt, я использую команду:
openssl enc -d -aes-256-cbc -salt -pbkdf2 -in open_encrypted.txt -out new.txt -pass file:key_dec_private.pem
Но расшифровка вовсе не работает.
Однако, когда я использую следующие команды для шифрования и расшифровки, они на самом деле работают: Шифрование:
openssl pkeyutl -encrypt -pubin -inkey key_public.pem -in open.txt -out open_encrypted.txt
Расшифровка:
openssl pkeyutl -decrypt -inkey key_enc_private.pem -in open_encrypted.txt -out new.txt
Кажется, я делаю что-то неправильно, когда использую команду openssl-enc.
Спасибо за помощь.
openssl enc
совсем не использует RSA; она только выполняет симметричное шифрование и дешифрование и, как правило (включая ваш случай), использует ключ, производный от парольной фразы. То, что вы делаете, это используете первую строку текста в файле с публичным или приватным ключом в качестве парольной фразы — и -----BEGIN PUBLIC KEY-----
отличается от -----BEGIN ENCRYPTED PRIVATE KEY-----
, так что вы пытаетесь дешифровать с неправильной парольной фразой, и это не удаётся. (Более того, поскольку миллионы людей по крайней мере знают, что всегда содержится в первых строках этих файлов, ваши парольные фразы совершенно небезопасны.)
pkeyutl
использует криптографию с открытым ключом, как шифрование/расшифрование, так и подпись/проверка, включая RSA; старая и теперь не рекомендуемая rsautl
работает только с RSA. Однако использование RSA напрямую ограничивает ваши данные, не позволяя сделать их больше, чем модуль RSA минус допуск для заполнения, что в вашем случае составляет около 240 байт, что обычно бывает от 3 до 12 строк. Хотя некоторые текстовые файлы такие короткие, большинство из них — нет, и тогда ваша схема проваливается.
Обычно для защиты нетривиальных данных RSA (или другим ПКШ) используется гибридное шифрование: данные шифруются с помощью симметричного алгоритма (который не имеет ограничений или имеет очень большое ограничение) и случайно сгенерированным одноразовым ключом, обычно называемым DEK (ключ шифрования данных), и этот DEK (который фиксирован и имеет меньшее значение) шифруется с помощью RSA; получатель использует RSA для дешифровки DEK и использует DEK для симметричной дешифровки данных. Как отмечено в Википедии, PGP делает это; также делает это бывший PKCS7, который заменен CMS и S/MIME; и XMLenc, который больше не используется. Таким образом, созданы различные схемы, которые разработали различные люди и организации, но ни одна из них (на данный момент) не получила значительного признания — за исключением JWE, и я не видел, чтобы она использовалась для больших данных, хотя это возможно.
OpenSSL поддерживает гибридное шифрование/дешифрование файлов с использованием форматов CMS или S/MIME, хотя в названиях немного путаницы: openssl smime
— это более старая функция и поддерживает как S/MIME, так и форматы CMS, но только для операций, определенных в их ранних версиях; openssl cms
— это более новая функция, которая снова поддерживает оба формата, но для расширенного набора операций. Поскольку ‘enveloped’ -encrypt
и -decrypt
были в раннем наборе, вы могли бы использовать любой из них, но в общем случае лучше использовать более новую версию.
О, и теперь, когда я смотрю на существующие вопросы, уже предложенные Stack, это в основном уже освещено в Как зашифровать большой файл с помощью OpenSSL, используя ключи RSA? и Как использовать неподписанный открытый ключ для шифрования большого файла с использованием openssl?.
Ответ или решение
Вопрос о шифровании файлов с использованием OpenSSL и ключей RSA демонстрирует часто встречающуюся путаницу между асимметричным и симметричным шифрованием. Эта ошибка довольно распространена, поскольку команда openssl enc
исходит из предположения о симметричном шифровании, в то время как RSA — это асимметричный метод.
Теория
Асимметричное шифрование, такое как RSA, предполагает использование пары ключей: публичный ключ для шифрования и соответствующий ему приватный ключ для дешифрования. RSA находит свое применение в безопасной передаче симметричных ключей, а не в шифровании больших объемов данных напрямую. Это связано с тем, что данные, которые могут быть зашифрованы напрямую с помощью RSA, ограничиваются размером ключа минус некоторые байты для заполнения.
С другой стороны, симметричные алгоритмы, такие как AES, предназначены для обработки больших объемов данных и требуют только одного ключа для шифрования и дешифрования. Часто используется метод гибридного шифрования, который сочетает оба подхода: симметричный алгоритм шифрует данные, а асимметричный защищает ключ для симметричного шифрования.
Пример
В примере, указанном в вопросе, был сгенерирован зашифрованный приватный ключ с помощью команды:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key_enc_private.pem -aes256
После этого использовался публичный ключ для шифрования, и это приводило к неудаче.
Ошибкой явилось использование команды openssl enc
для RSA-криптографии. Эта команда предназначена для симметричного шифрования, и в вашем случае она просто интерпретировала содержимое ключевого файла как парольную фразу. Поскольку структура публичного и приватного ключей различна, использование их в качестве пароля было неэффективным и небезопасным.
Для шифрования данных публичным ключом с использованием RSA-метода следует использовать pkeyutl
:
openssl pkeyutl -encrypt -pubin -inkey key_public.pem -in open.txt -out open_encrypted.txt
Для дешифровки – соответствующая команда:
openssl pkeyutl -decrypt -inkey key_enc_private.pem -in open_encrypted.txt -out new.txt
Однако тут важно отметить, что этот подход подходит для небольших данных.
Применение
Рассмотрим, как корректно применять гибридное шифрование для работы с файлами значительных размеров. Для этого существует стандартная практика, включающая шифрование данных с помощью симметричного алгоритма (например, AES), при этом сам симметричный ключ шифруется с использованием RSA.
Шаги использования гибридного подхода:
-
Генерация случайного симметричного ключа (DEK):
Создайте симметричный ключ для использования с алгоритмом AES. -
Шифрование данных с использованием симметричного алгоритма:
openssl enc -aes-256-cbc -salt -in open.txt -out open_encrypted.txt -pass pass:your-symmetric-key
-
Шифрование DEK с использованием RSA:
echo -n "your-symmetric-key" | openssl pkeyutl -encrypt -pubin -inkey key_public.pem -out encrypted_key.bin
-
Дешифровка DEK с использование RSA:
openssl pkeyutl -decrypt -inkey key_enc_private.pem -in encrypted_key.bin -out decrypted_key.txt
-
Дешифрование данных с использованием раскрытого симметричного ключа:
openssl enc -d -aes-256-cbc -salt -in open_encrypted.txt -out new.txt -pass file:decrypted_key.txt
Этот подход широко используется в таких стандартах, как CMS, S/MIME, JWE, где OpenSSL поддерживает функции работы с этими форматами, хотя и с некоторыми особенностями в синтаксисе команд. Использование гибридного шифрования позволяет не только эффективно шифровать большие объемы данных, но и обеспечивает высокий уровень безопасности.