Обратный вызов пароля для чтения открытого ключа с помощью OpenSSL API

При использовании криптографии с открытым ключом часто принято хранить закрытые ключи в зашифрованном формате, поскольку они, конечно, должны быть секретом. Это отражено в API OpenSSL C, который предоставляет такие функции, как PEM_write_PrivateKey, который принимает в качестве аргументов функции необязательный шифр, используемый для шифрования ключа (например, AES). Затем при считывании зашифрованного ключа обратно с диска OpenSSL API предоставляет такие функции, как PEM_read_PrivateKey, что позволяет пользователю предоставлять указатель функции, используемый в качестве обратного вызова, чтобы приложение могло предоставить OpenSSL пароль для зашифрованного ключа.

Но что меня смущает, так это то, что OpenSSL API, похоже, также позволяет пользователю предоставлять обратный вызов пароля при чтении ключа Общественные. Например, одна подпись функции API для чтения в открытом ключе:

 EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
                                        pem_password_cb *cb, void *u);

Итак, какова цель обеспечения обратного вызова пароля при чтении ключа общественный? AFAIK не имеет смысла шифровать открытый ключ, поскольку открытый ключ по определению должен быть доступен для широкой публики. Итак, почему у OpenSSL API здесь есть параметр функции, который принимает обратный вызов пароля?

Вы смешиваете язык C с C++? У вас есть оба тега, и это разные языки.

Thomas Matthews 19.09.2018 19:10

Нет, я просто поставил и то, и другое, поскольку API OpenSSL можно использовать из любого

Siler 19.09.2018 19:10

В этом случае вам следует добавить паскаль, FORTRAN и множество других языков, которые будут взаимодействовать с интерфейсом в стиле C. Лучше всего, если вы просто пометите целевой язык, который вас интересует. Если вас не волнует язык, используйте агностик языка.

user4581301 19.09.2018 19:12
Любой PEM может быть зашифрован, даже открытые ключи, хотя как правило только закрытые ключи. Но, возможно, эмитент хочет выдать открытый ключ, но ограничить круг лиц, которые могут его использовать, с помощью пароля, который предоставляется только авторизованным пользователям.
Remy Lebeau 19.09.2018 19:23
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
670
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как упомянуто в этот комментарий, любые данные в кодировке PEM могут быть зашифрованы. Шифрование сообщений для почты с повышенной конфиденциальностью (PEM) определено в RFC 1421, и в контексте вашего вопроса интересно взглянуть на пример сообщения в Раздел 4.6 Обзор инкапсулированных полей заголовка

-----BEGIN PRIVACY-ENHANCED MESSAGE-----
Proc-Type: 4,ENCRYPTED
Content-Domain: RFC822
DEK-Info: DES-CBC,F8143EDE5960C597
Originator-ID-Symmetric: [email protected],,
Recipient-ID-Symmetric: [email protected],ptf-kmc,3
Key-Info: DES-ECB,RSA-MD2,9FD3AAD2F2691B9A,
          B70665BB9BF7CBCDA60195DB94F727D3
Recipient-ID-Symmetric: [email protected],ptf-kmc,4
Key-Info: DES-ECB,RSA-MD2,161A3F75DC82EF26,
          E2EF532C65CBCFF79F83A2658132DB47

LLrHB0eJzyhP+/fSStdW8okeEnv47jxe7SJ/iN72ohNcUk2jHEUSoH1nvNSIWL9M
8tEjmF/zxB+bATMtPjCUWbz8Lr9wloXIkjHUlBLpvXR0UrUzYbkNpk0agV2IzUpk
J6UiRRGcDSvzrsoK+oNvqu6z7Xs5Xfz5rDqUcMlK1Z6720dcBWGGsDLpTpSCnpot
dXd/H5LMDWnonNvPCwQUHt==
-----END PRIVACY-ENHANCED MESSAGE-----

Если посмотреть на ветвь OpenSSL 1.1, то в ней есть функция PEM_read_bio(), которая поддерживает чтение такого сообщения и разбивает его на его имя (как указано в верхней строке), заголовок (пары имя-значение ниже) и данные (закодированные в base64 вещи):

 int PEM_read_bio(BIO *in, char **name, char **header,
                  unsigned char **data, long *len);

Все функции OpenSSL PEM_read_XYZ() в какой-то момент вызывают его из PEM_bytes_read_bio(), потому что все они реализованы одинаково с помощью расширений макросов. Эта функция содержит следующие вызовы:

PEM_read_bio(bp, &nm, &header, &data, &len)

чтобы разделить сообщение, затем

PEM_get_EVP_CIPHER_INFO(header, &cipher);

чтобы выяснить, какой тип информации о шифровании находится в заголовке этого сообщения, и заполнить им объект EVP_CIPHER_INFO, а затем

PEM_do_header(&cipher, data, &len, cb, u);

для расшифровки данных на основе найденной зашифрованной информации - при необходимости снова. Обратите внимание на параметр cb, который обозначает обратный вызов, механизм для получения ввода для любой ключевой фразы, если это необходимо.

Что может сбить с толку, так это то, что некоторые форматы закрытых ключей, такие как, например, PKCS # 8, также имеют свой собственный механизм хранения информации о шифровании независимо от кодировки PEM. С технической точки зрения, должна быть возможность применять шифрование к таким ключам дважды: один раз на уровне PEM и один раз на уровне PKCS # 8. Инструменты OpenSSL для генерации или преобразования ключей в формате PKCS # 8, похоже, не предлагают такой возможности. Кроме того, похоже, что ни один из инструментов не предоставляет возможность шифрования любых сгенерированных файлов PEM с открытым ключом, если также не включен закрытый ключ.

Вы можете проверить некоторые результаты, чтобы убедиться, что они соответствуют моей истории. Во-первых, создание пары ключей RSA в формате PKCS # 1, ничего не зашифровано:

$ openssl genrsa
Generating RSA private key, 2048 bit long modulus (2 primes)
.................+++++
............+++++
e is 65537 (0x010001)
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAlcnR/w7zPoLrhuqFvcfz5fn8DFb0fEcCKOKSj+x+JJxGth9P
rJbxkt4pRXxbMIL0fX59HN5bRvQh2g59l/kfr30kCOnclap9nRrohWyg2i7720Cw
<truncated>

Затем та же команда, но с использованием шифрования, которое происходит на уровне PEM, как вы можете видеть в заголовках:

$ openssl genrsa -des3
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................+++++
....................+++++
e is 65537 (0x010001)
Enter pass phrase:
Verifying - Enter pass phrase:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,D90861647707F687

DIupLghCjcvpLenqAAULaJj1EDvUUfc2Xc58YVh7rMTSVgLwZ+9CtnUQJcup4aUQ
a1EdGXTadwBQB2jTtiFJbH67/5D26PHXPnM+YN2rnoReOExVS7hKu3DTq7c4j6a3
<truncated>

Наконец, сгенерирован аналогичный ключ, но теперь для PKCS # 8, который имеет собственное шифрование и, следовательно, не шифруется на уровне PEM. Вы можете видеть, что заголовков PEM нет.

$ openssl genpkey -algorithm RSA -des3
.........................................+++++
...........................................................................+++++
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIV0Ih4bsI6egCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECNOim8HAN8j5BIIEyEe05hHtc8HL
<truncated>

Если все мои рассуждения верны, то запрос «Введите парольную фразу PEM» неточен, поскольку это шифрование не уровня PEM, а шифрование уровня PKCS # 8.

Другие вопросы по теме