Задать вопрос
@Drovosek01

Почему OpenSSL в macOS 15 требует приватный ключ, чтобы зашифровать текст?

Предисловие.

Есть приватный и публичный ключи, сгенерированный в shell:
openssl genpkey -algorithm RSA -out private_key.pem
openssl rsa -in private_key.pem -pubout -out public_key.pem


Есть определенный скрипт, он пакует указанный файл в 7z-архив с паролем, а текст-пароль от архива шифрую публичным ключом и этот шифр сохраняю в файл рядом с запароленным архивом.
Например так:
printf "$temp_password" | openssl pkeyutl -encrypt -inkey "$public_key_file_path" -pubin -in /dev/stdin -out "$password_file_name.pwd"

На macOS 12.7 Monterey Intel это работает без проблем.

Начал тестировать код на macOS 15.1 Sequoia M1 и этот код выдает ошибку
spoiler
unable to load Private Key
8170190912:error:09FFF06C:PEM routines:CRYPTO_internal:no start line:/AppleInternal/Library/BuildRoots/4b66fb3c-7dd0-11ef-b4fb-4a83e32a47e1/Library/Caches/com.apple.xbs/Sources/libressl/libressl-3.3/crypto/pem/pem_lib.c:694:Expecting: ANY PRIVATE KEY
Error initializing context
usage: pkeyutl [-asn1parse] [-certin] [-decrypt] [-derive] [-encrypt]
    [-hexdump] [-in file] [-inkey file] [-keyform fmt]
    [-out file] [-passin arg] [-peerform fmt]
    [-peerkey file] [-pkeyopt opt:value] [-pubin] [-rev]
    [-sigfile file] [-sign] [-verify] [-verifyrecover]

 -asn1parse         ASN.1 parse the output data
 -certin            Input is a certificate containing a public key
 -decrypt           Decrypt the input data using a private key
 -derive            Derive a shared secret using the peer key
 -encrypt           Encrypt the input data using a public key
 -hexdump           Hex dump the output data
 -in file           Input file (default stdin)
 -inkey file        Input key file
 -keyform fmt       Input key format (DER or PEM (default))
 -out file          Output file (default stdout)
 -passin arg        Key password source
 -peerform fmt      Input key format (DER or PEM (default))
 -peerkey file      Peer key file
 -pkeyopt opt:value Public key options
 -pubin             Input is a public key
 -rev               Reverse the input data
 -sigfile file      Signature file (verify operation only)
 -sign              Sign the input data using private key
 -verify            Verify the input data using public key
 -verifyrecover     Verify with public key, recover original data

Это проблема решается так - для шифрования текста, необходимо использовать приватный ключ, а не публичный, то есть, например, такой код:
printf "$temp_password" | openssl pkeyutl -encrypt -inkey "$private_key_file_path" -pubin -in /dev/stdin -out "$password_file_name.pwd"


Вопросы:
1. Почему так?
2. Есть ли универсальный вариант, чтобы код работал нативно на обеих macOS?
  • Вопрос задан
  • 56 просмотров
Подписаться 1 Простой 2 комментария
Решения вопроса 1
@Drovosek01 Автор вопроса
Нашел универсальное решение - необходимо шифрование текста-пароля выполнять с sudo.
printf "$temp_password" | sudo openssl pkeyutl -encrypt -inkey "$public_key_file_path" -pubin -in /dev/stdin -out "$password_file_name.pwd"

Тогда ошибок нет.

Но тем не менее, вопрос о том, почему в macOS Monterey это работает без проблем без sudo - остался.

spoiler
А какая у вас macOS?

Проверьте кто-нибудь у себя, у вас этот код выполнится с ошибками или без ошибок?
mkdir test_dir_for_openssl
cd test_dir_for_openssl
openssl genpkey -algorithm RSA -out private_key.pem
openssl rsa -in private_key.pem -pubout -out public_key.pem
temp_password=Test123
public_key_file_path=public_key.pem
password_file_name=encrypted_password_file
printf "$temp_password" | openssl pkeyutl -encrypt -inkey "$public_key_file_path" -pubin -in /dev/stdin -out "$password_file_name.pwd"


===

В итоге проблема оказалась в том, что на macOS Monterey у меня был установлен openssl из brew, а на macOS Sequoia был стандартный системный openssl.

Системный openssl в macOS имеет немного иную реализацию и чтобы с ним работала команда для дешифрования текста с помощью приватного ключа, необходимо поменять аргументы местами.
Вот так работает правильно:
printf "$temp_password" | /usr/bin/openssl pkeyutl -encrypt -in /dev/stdin -pubin -inkey "$public_key_file_path" -out "$password_file_name.pwd"


Тут также об этой проблеме писали - https://github.com/openssl/openssl/issues/8701
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы