Не удалось получить закрытый ключ с помощью PEM_read_bio_PUBKEY()

Вопрос или проблема

Я пытался загрузить открытый ключ и не смог.

Сначала я создал закрытый и открытый ключи с помощью 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. Давайте рассмотрим возможные причины этой ошибки и пути их решения.

  1. Формат ключа: Убедитесь, что файл test-public.pem действительно содержит открытый ключ в формате PEM. Обычно такой файл начинается с заголовка -----BEGIN PUBLIC KEY----- и заканчивается -----END PUBLIC KEY-----. Однако, поскольку вы создавали самозаверяющий сертификат, файл, скорее всего, будет иметь заголовки -----BEGIN CERTIFICATE----- и -----END CERTIFICATE-----.

  2. Использование подходящей функции для загрузки ключа: Ваша программа пытается считать публичный ключ, но так как сертификат создаётся с помощью 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;
}
  1. Компиляция и запуск: Убедитесь, что вы компилируете ваш код с корректными флагами и библиотеки OpenSSL. Ваше командное выполнение компиляции выглядит корректно.

  2. Проверка ошибок: Добавьте дополнительные вызовы perror() или логирование ошибок, которые помогут вам подробнее понять, где происходит сбой.

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

Оцените материал
Добавить комментарий

Капча загружается...