Вопрос или проблема
Я пытался загрузить открытый ключ и не смог.
Сначала я создал закрытый и открытый ключи с помощью openssl следующим образом.
$ openssl genrsa -out test-priv.pem 4096
$ openssl req -subj '/C=US/ST=Texas/L=Fort Worth/O=ABC Corporation, Inc./OU=Software/CN=abc_corp.com' -x509 -nodes -key test-priv.pem -out test-public.pem -days 365 -addext keyUsage=digitalSignature -addext extendedKeyUsage=codeSigning,emailProtection
Тестовый код выглядит следующим образом.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <openssl/pem.h>
EVP_PKEY *load_pubkey(const char *file)
{
BIO *key = NULL;
EVP_PKEY *pkey = NULL;
if (file == NULL)
{
printf("файл ключа не указан\n");
goto end;
}
key = BIO_new(BIO_s_file());
if (key == NULL)
{
goto end;
}
if (BIO_read_filename(key, file) <= 0)
{
printf("Ошибка открытия : %s\n", file);
goto end;
}
pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
end:
if (key != NULL)
BIO_free(key);
if (pkey == NULL)
printf("Не удалось загрузить файл ключа : %s\n", file);
return (pkey);
}
int main(int argc, char *argv[])
{
load_pubkey((const char *)argv[1]);
return 0;
}
Я скомпилировал этот тестовый код следующим образом.
$ gcc key_test.c -l ssl -l crypto -o key_test
Затем запустил программу следующим образом.
$ key_test test-public.pem
И сообщение об ошибке, которое я получил, гласит: “Не удалось загрузить файл ключа : test-public.pem”. Вы не видите, что я сделал что-то не так?
Ответ или решение
На первый взгляд, проблема, с которой вы столкнулись, заключается в том, что функция PEM_read_bio_PUBKEY()
не может правильно загрузить открытый ключ из файла test-public.pem
. Давайте рассмотрим возможные причины этой ошибки и пути их решения.
-
Формат ключа: Убедитесь, что файл
test-public.pem
действительно содержит открытый ключ в формате PEM. Обычно такой файл начинается с заголовка-----BEGIN PUBLIC KEY-----
и заканчивается-----END PUBLIC KEY-----
. Однако, поскольку вы создавали самозаверяющий сертификат, файл, скорее всего, будет иметь заголовки-----BEGIN CERTIFICATE-----
и-----END CERTIFICATE-----
. -
Использование подходящей функции для загрузки ключа: Ваша программа пытается считать публичный ключ, но так как сертификат создаётся с помощью
openssl req
и сохраняется в файлtest-public.pem
, вам, возможно, нужно использовать функциюPEM_read_bio_X509()
для считывания сертификата, а затем получить из него публичный ключ. Вот как это можно сделать:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
EVP_PKEY *load_pubkey(const char *file)
{
BIO *bio = NULL;
X509 *x509 = NULL;
EVP_PKEY *pkey = NULL;
if (file == NULL)
{
printf("Файл ключа не указан\n");
goto end;
}
bio = BIO_new(BIO_s_file());
if (bio == NULL)
{
perror("Не удалось создать BIO");
goto end;
}
if (BIO_read_filename(bio, file) <= 0)
{
perror("Ошибка при открытии файла");
goto end;
}
// Чтение сертификата
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
if (x509 == NULL)
{
printf("Не удалось загружать сертификат из файла: %s\n", file);
goto end;
}
// Извлечение публичного ключа из сертификата
pkey = X509_get_pubkey(x509);
end:
if (bio != NULL)
BIO_free(bio);
if (x509 != NULL)
X509_free(x509);
if (pkey == NULL)
printf("Не удалось загрузить публичный ключ из файла: %s\n", file);
return pkey;
}
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("Укажите файл с публичным ключом\n");
return 1;
}
EVP_PKEY *pubkey = load_pubkey((const char *)argv[1]);
if (pubkey != NULL)
{
printf("Публичный ключ успешно загружен.\n");
EVP_PKEY_free(pubkey);
}
return 0;
}
-
Компиляция и запуск: Убедитесь, что вы компилируете ваш код с корректными флагами и библиотеки OpenSSL. Ваше командное выполнение компиляции выглядит корректно.
-
Проверка ошибок: Добавьте дополнительные вызовы
perror()
или логирование ошибок, которые помогут вам подробнее понять, где происходит сбой.
Если вы внесете вышеупомянутые изменения и будете использовать правильные функции для загрузки публичного ключа из сертификата, ваша программа должна заработать корректно. Если после этих изменений проблема всё ещё сохраняется, попробуйте проверить возможность работы с другими файлами сертификатов, чтобы исключить возможность повреждения файла.