2017-01-14 7 views
2

Я пытаюсь загрузить открытый ключ RSA в свою программу. Я использую OpenSSL LIB в C. Ключ определен в заголовочном файле crypt.h:Ошибка передачи открытого ключа RSA из строки в RSA * struct

#define PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" \ 
        "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuDcT2OiToi9edqil/3ha\n" \ 
        "1MMrgqYvdYObRkb8C5SZtf8iv4LynuHi3hvEtybqFW84Uf2l3Dxuz3IWVp2v1C2f\n" \ 
        "cUxwf+hFqL4Nt2Ww/XOKLtFXTSX/2fPYoelmLja2grHPSuFx6N4gtDUXRIGSYXIz\n" \ 
        "c2GBx8lOiOP+qUguFmWZ9E0GiMLvh4XUQUzTGr4ZNNoc5LODdO0g7beFFqhntt9w\n" \ 
        "EKdceGQtA7Zyt5l13x0lj+RONdPJkDFZrNGdqDwNUSog9mufpvR1P2UW09pC+lzy\n" \ 
        "z32P+w0U3Za4zv4Btis9ky16vaqdN/KlDWJRt+4W9TQSAL0x9w708OQr0Sf2CXNq\n" \ 
        "EobSLZ/aybe75yQmzFqmn10X+NuwTtJkArIKK7JONCBSxjohQmTZw0U497TCEHia\n" \ 
        "itzgsHNLf1of31G/3GK5rCkm9fl39nnrg0yJi1cONTDjSHzKlrPhA584jFRD0CIO\n" \ 
        "VNHYgsVLuFQuJ0WkZON8uEZELXN1ZyWnmPXH8wSwxjud65JD4JSQornCXorBMfxd\n" \ 
        "DFEeeNk8tjgPMaCTLFNP/gfVDzkvcct9RoC8uZxHk8zgrGOwuxOZ/ZyihE7M8v0i\n" \ 
        "+VwG9iMrPl8W3+KqunIt/FB4Le1vJ0yYorK64DRNdeMAIsYq2iFWO3GXNsX631/K\n" \ 
        "EuZJS8tGNhK9dF5umo0GceUCAwEAAQ==\n" \ 
        "-----END PUBLIC KEY-----\n" 

Ключ RSA должен быть сохранен в RSA * структуре. Для этого я использую глобальную переменную.

RSA *rsaPubkey; 

The main() вызывает функцию, которая будет принимать PUBLIC_KEY и передать его в rsaPubkey. Функция показана ниже:

#include "crypt.h" 

int EVP_PKEY_get_type(EVP_PKEY *pkey) { 
    if (!pkey) 
     return EVP_PKEY_NONE; 

    return EVP_PKEY_type(pkey->type); 
} 

int PublicRSAKeyToStruct(const char *pubKey) { 
    BIO* bio; 
    bio = BIO_new_mem_buf(pubKey, (int)sizeof(pubKey)); 
    if (bio == NULL) { 
     printf("bio"); 
     return -1; 
    } 

    EVP_PKEY* pkey; 
    PEM_read_bio_PUBKEY(bio, &pkey, NULL, NULL); 
    if (pkey == NULL) { 
     printf("pkey"); 
     return -1; 
    } 

    int type = EVP_PKEY_get_type(pkey); 
    if (type != EVP_PKEY_RSA && type != EVP_PKEY_RSA2) { 
     printf("get type"); 
     return -1; 
    } 

    rsaPubkey = EVP_PKEY_get1_RSA(pkey); 
    if (rsaPubkey == NULL) { 
     printf("pubkey"); 
     return -1; 
    } 

    EVP_PKEY_free(pkey); 
    BIO_free(bio); 
    return 0; 
} 

Мы называем функцию вроде этого:

status = PublicRSAKeyToStruct(PUBLIC_KEY); 
if (status == -1) { 
    exit(EXIT_FAILURE); 
} 

Моя проблема заключается в том, что функция PublicRSAKeyToStruct() бросает мне определенную ошибку ниже пользователя:

get type 

Этот означает, что мы не смогли пройти EVP_PKEY_get_type(). Я не понимаю, почему это происходит. Я также не знаю, проблема в предыдущих шагах.

+1

Каково значение 'type' при возникновении ошибки? – Alden

+0

@ Алден - это нуль (0). Так что где-то есть сбой? –

+0

@GuyL: не делайте этого. Данные показаны в формате PUBKEY = SPKI и НЕ относятся к формату RSA PUBLIC KEY (raw PKCS1). –

ответ

1

Ваш запрос PEM_read завершился неудачно, потому что BIO, который вы ему предоставили, не имеет доступа к правильным данным, но вы не проверили возвращаемое значение, и вы не инициализировали pkey, так что, хотя это недействительно, ваш pkey == NULL чек doesn ' t поймать его. Как описано в man-странице вашей системы (кроме Windows) или on the web, второй аргумент для BIO_new_mem_buf должен быть либо числом байтов в буфере, либо -1, если буфер содержит строку C с нулевым завершением - и строковый литерал, подобный вашему дает строку с нулевым завершением, поэтому -1 подходит - но sizeof(apointer) не является ни тем, ни другим.

Остальная часть вашего кода верна и работает нормально, если вы даете ей действительный номер EVP_PKEY*.

+0

Я закрепил его до 'bio = BIO_new_mem_buf (pubKey, -1);'. Теперь это работает. Пожалуйста, добавьте его в свой ответ. Также добавьте ссылку на https://linux.die.net/man/3/bio_new_mem_buf, которые предлагают добавить '-1' во второй параметр. Измените это, чтобы другие могли это понять. В любом случае я приму свой ответ. (пожалуйста, добавьте эти сведения). –

+0

для личных ключей Я использую 'PEM_read_bio_PrivateKey()' правильно? –

+0

@GeorgeGkas: Я предпочитаю не ссылаться на linux.die.net для вещей, которые варьируются от версии к версии, и OpenSSL действительно отличается во многих областях, но не AFAIR для memBIO, поэтому вместо этого я использовал свой предпочтительный стиль. Да, если у вас есть закрытый ключ в одном из нескольких форматов PEM, которые использует OpenSSL, 'PEM_read_bio_PrivateKey' будет читать его. Обратите внимание, что (в отличие от публичных) privatekeys часто шифруются паролем, и если это так, ваш вызов должен предоставлять либо сам пароль, либо обратный вызов, который получает пароль. –

 Смежные вопросы

  • Нет связанных вопросов^_^