Хобрук: Ваш путь к мастерству в программировании

Не могу установить открытый/закрытый ключ в OpenSSL

Я пытаюсь установить открытый и закрытый ключ в EVP_PKEY в С++ из строки. Однако, даже после нескольких онлайн-примеров, PKEY всегда будет NULL. Вот код для воспроизведения проблемы (это для закрытых ключей, но эффект тот же для открытых ключей):

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <string>
#include <iostream>

int main()
{
    EVP_PKEY *keypair;
    keypair = NULL;

    std::string privateKey = "-----BEGIN PRIVATE KEY-----MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCuKz6ENUUniXU9CelOgD6oTlmkxPWZoaeBUVXLwlh2aE4As/8RMaIpTsxq9M8UmY7L69GVHo51+wmACrW1ftEa3S5rVLRuOrwFNYGLUlrbji4huD5ipxS0MbxKE+lc/VYLTN26zPI8pl8Qb38eESiLXZ7uNO1XRisKxjixy/J4CMMDdn0UFTjKxXmdQluN67T1JlzGzALRKYFMLF8H+VLqhW6ygFE1OjjJ8zwQuP8t2mRBFLXwH1bwffXX4rUwAb+C9FXHWEn5SJv8aoj/9awEw7cYWa0eeAbl2TfPW+QcbzcITp9L9g/9/8M9rH0wqURCzv+z7P0Wkc2JrdcA6vIDAgMBAAECggEAHjFO8BpP96+jjEZIlJw0wHZ8ocynCs/0Or2/0sfJEBW61/JcGD3zb5fCZhQ0Rczs7TrfJSub5KX1GqZAo8rtMuv+3QpdEPLLn1eMMnu/VmpKYvwOjImMVER+8JSNEtqz7NeRZI2cvJjWyAGcFrlAvxAmugKg1k1Krt53+5JwYRBSWQb+05egOXVoQahBJbLWbWJrUFBjmsCAkF/1MvnJ9h2CAmrJIOWMjzWgs2MyUSzAE0I0vLG/mtlUXUGWA7EFAY6BNGWUaHdd6Cy2GhlCoEEL4gYATdtQK1k5r/5O54gTJq1rISEjicXp/qLiFIEa8feuCFGWfFQnIXlmvRZ/gQKBgQDkA8gdQ5XTBQHdcasIeNjJTgmB1W0cugYmUB01O0Kk0O5sVAh0LtWkIF6Tw5Od3olYRt/UNpegOvYoc+lm3kLS14NPcd5P3Zdl/i9NcWq8QF3uNzT5NfLi2nh8lyH2q41Koc2skRQsIQkZEOgLjP2+n3SsZf0PBOE9rYeO9rkSwwKBgQDDi6CWVOSH4suSGLJeauc/j7/MwMAtM7r5cOegh1tJZrAhiL7DXeWM9iT2VWU+9fiH16Je6+0PuXPmkcj3T/E/fSWQ+6n0YjnvIuyQGxMFXW2Zwssxgv51iD+EO88lFD+2wR6YUHl0wPeSQTUvHM3xUp/uOG0yUvoCijqxFCYvwQKBgCvy7qd1V3ONC4b7WdQQNvjWKc70rEtVL8pCtt6DxZyvCMWojNiYDmXMN26Ty+gp9J8nSg1FWIRx2PCDJwHE5WxuTckKUadjNsNZ8xQiQEh4v6Ii0fsXAvHm2kJpfwpklp9EALi6XgEDfRVvxMo1KtOLOJniLpyufBu/TtmnhJSxAoGAG+CI+UWK+vBTMzXAIAO/iek1X7xO6WLJkgwNiW4ijnlMPMug3ntBYXIp3NBZybsJPlx4cm3R8v7uTf2Ul+VWsEVoGJ44IXXranMhJH4nnQkvuc7yZtGU8y6EV5arNk8Hskcf1HkMh5+G69vN+DR0C6ZK1IxIzPbVW41XRq1nsEECgYBmtbY5dIvRemh4FdsMjdUuQcurvyQpEIwdczWurRXfKCuWtbVvn1arTQ/nL+kUixMjPueBInX90vxP+ptoPAHXOMKuZx+bFNwIQZ+OIBQ1WPUG8nV4o7tRZOkIPSy8YVz8UFQuuA6WF5W2kh3gc3iPrQt5JjspkWPDuC1taQo/pw==-----END PRIVATE KEY-----";

    BIO *bio = BIO_new(BIO_s_mem());
    if(BIO_write(bio, (unsigned char*)privateKey.c_str(), (size_t)privateKey.size()) != (int)privateKey.size())
    {
        BIO_free_all(bio);
        return 0;
    }

    PEM_read_bio_PrivateKey(bio, &keypair, NULL, NULL);

    BIO_free_all(bio);

    if(keypair == NULL)
    {
        std::cout << "error";
    }
    else
    {
        return 0;
    }
}

Что я делаю не так?

28.04.2015

Ответы:


1

Передаваемый вами закрытый ключ недействителен; отсутствуют новые строки. Один должен быть сразу после заголовка -----BEGIN PRIVATE KEY-----, еще один перед соответствующим нижним колонтитулом и один после каждых 64 символов в теле, например.

std::string privateKey = "-----BEGIN RSA PRIVATE KEY-----\n"
    "MIIEogIBAAKCAQEAris+hDVFJ4l1PQnpToA+qE5ZpMT1maGngVFVy8JYdmhOALP/\n"
    "ETGiKU7MavTPFJmOy+vRlR6OdfsJgAq1tX7RGt0ua1S0bjq8BTWBi1Ja244uIbg+\n"
    /* ... */
    "5y/pFIsTIz7ngSJ1/dL8T/qbaDwB1zjCrmcfmxTcCEGfjiAUNVj1BvJ1eKO7UWTp\n"
    "CD0svGFc/FBULrgOlheVtpId4HN4j60LeSY7KZFjw7gtbWkKP6c=\n"
    "-----END RSA PRIVATE KEY-----";
28.04.2015
  • Передаваемый закрытый ключ недействителен; в нем отсутствуют символы новой строки. - Я удивлен, что OpenSSL еще не исправил это... Это произвольное ограничение в 1000 символов в RFC 821 и RFC 1421. Нет причин прерывать обработку из-за отсутствия новых строк, которые немедленно удаляются. 29.04.2015
  • Эти RFC здесь не очень уместны, так как это не электронная почта. RFC 7468 на самом деле устанавливает более строгое требование, согласно которому каждая строка должна содержать ровно 64 символа, кроме последней строки. . Однако, даже если бы это было не так, строки заголовка/конечной строки в любом случае должны быть отделены от данных, поэтому все равно будет отсутствовать как минимум две новые строки. 29.04.2015
  • для полноты, RFC 7468 не существовало, когда эти подпрограммы были врезаны :) Кодировщик Base64 был взят из RFC электронной почты, а кодирование PEM взято из RFC PEM. Но приятно видеть, что поведение, наконец, вызвало. И вы правы насчет инкапсулированных границ заголовков — для их очерчивания нужны новые строки. 29.04.2015
  • Новые материалы

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..