2013-05-21 3 views
3

Я пытаюсь прочитать в файле AES-128-CBC зашифрованный ключ PEM, сгенерированный с использованием Ruby с API OpenSSL. Код, который генерируется ключ PEM является следующее:Чтение PEM-форматированного ключевого файла RSA с API OpenSSL C

OpenSSL::PKey::RSA.new(2048).to_pem(OpenSSL::Cipher::AES.new('128-CBC'), "password") 

Вот код, который считывает файл PEM:

RSA *rsa; 

BIO *pem = BIO_new(BIO_s_mem()); 
BIO_puts(pem, "-----BEGIN RSA PRIVATE KEY-----\n" 
    "Proc-Type: 4,ENCRYPTED\n" 
    "DEK-Info: AES-128-CBC,BB13D39833DD6ED1FF9843644E7981EE\n\n 
    "Eugt8JZNKQKErsabWkwfm3wQhU/Tmp9T0QaP5HM8VIWpZwKlDmRlSUDptADU6RPD\n" 
    "5VtG3DPieXcf+6deyARImid9sBBmQ9mK2omkNRcTMemqTOhAuaKBu78TMt9G4YSf\n" 
    "RjoXWSqu3jMwrlcGkpn7bIum8wImITRZ3p28oSzk9aDUNBrIU/2Si8DM4RYIZ/fK\n" 
    "Uvvgdok9dgcd0SjvucivX2HaGeg/IUz23q1jg9inDpimZvFJD1FJfGEUWDgyfJfa\n" 
    "M8JIxTKbWOPEopONDkT7u4dC5VcSjK29MVbfd7iCKFPMh5UN+c96rPxTng/OWyW5\n" 
    "0tvzHyyyvAG9p0Hx5Lr4pDbv21GHyu43sA6wbs9jWyqO3AB7CaoEEQhumwfLsdjj\n" 
    "YGrX6bWThpYv/XNBDmmvltHlKFfe01NCybivOb4KwBnvi45x21PBqaZCKDTFdEkL\n" 
    "iwDMTiG2iTxSUvPFLy30VFozE+pGyMcGDUyZDVqjsaqI/MRj8khnn5nyubXc27G3\n" 
    "8Kbsnlix2SW2M0VDxqiy9dyjcxXrkFRSnOFYVs1PFlgjFVTG4Mwh6CZxKw8mFVbi\n" 
    "EmLvUYwzoDZ1ve4VXSPp/vrKEh33JuHhM0vJOpqI6wqw0QR0I2o6etM1ZRJClPcw\n" 
    "VIcgcvwenEgLOkoHDqOr0IZQAtYWvAuqq822wKt258hc6z8+ALQf5iMroqk7ADd4\n" 
    "FlRLz4XTwqlg7pPtTde/emI1DT8dQWzq++QI0lr0CS/N1GXJKqTQDvauXLIiI3Qy\n" 
    "KfFYFpV9jyYfRfTjNtisI/edPtp98auK0mb9o/wS/hruFI9behgv63iW1IwAOXCW\n" 
    "ZlkWgobUH13gS864rL+AcrAXreo2j4dDQouTeRaJUEG0HoYTP65Zun/VsCi2aSOH\n" 
    "JwSnnmHz9OxvcGY80WJDN3kqOCBRIJoDKBv6jcOxGVCsVK+WSdGZ7cfb8lwp7aA8\n" 
    "8ND1bwL9FYkwkeIsoakj91iinqv4o3+3PUPgCU5oe68WYvAFjuU+criyf+EhmXJV\n" 
    "JQ1vFFZPrGzgntJz19uXXh1h2iwQPggRouJm2RozYwvv1nz4eQ40Y3eT1F9UOYJU\n" 
    "CKEhOtI2NpLeVOayqo8g9wO2oC+CQVhZhdYBE5o7pM7akFnYLvRg9s1UsWdcvT0G\n" 
    "IpFmejLSRJ/F954aQMHTUc6vBOJZH/VNC5Qt+ulFXl634Sr9wQQK2qlqSJyA04TR\n" 
    "1ixbCNOX71esvpFImsrlsO5oTA22T3h2GyJPUM10XhqGtDXtsTnal6smLna9U9B3\n" 
    "gTVxFWWukQOF5Lm8ZFQipo2loHWjkozTBc4REPYP44SoXJXstv7k4pt1cK7x6/2H\n" 
    "ElspXzjveqMhcrveWv1KaA2OGd+hGfUiNsCoIdapJjLz1Bd/+oIQ/ZWQeo0nRowE\n" 
    "R/HlbbED3V+fRIdJpgydFEAw6gK5E9sYJcgF7uf/n2NabFxxEZL3g6MJQ64Dtusg\n" 
    "DEH/MpvIYDSX4Navh1gTwCtOeG1CzW3diYaqbZK+UZCBLFU7j27YvVPSd6F2+Wud\n" 
    "WnAqU3S5BCPqk5OD3wqZv+sEcqJgGPGy1Gv0tl8ARJomdKAru03KsRn2eIWqR5/C\n" 
    "-----END RSA PRIVATE KEY-----\n"); 

// Retrieve RSA key from PEM file. 
rsa = PEM_read_bio_RSAPrivateKey(pem, NULL, pem_password_callback, "password"); 

А вот фиктивный пароль обратного вызова (не уверен, о цели этой функции, но я думаю, что это может вернуть длину пароля):

int pem_password_callback(char *buf, int max_len, int flag, void *pwd) 
{ 
    return 8; 
} 

в настоящее время rsa = ... часть не выдаст ошибку, но не возвращает хорошо сформированный результат либо.

+0

Как вам Знаете, что плохо сформировалось? – doptimusprime

+0

Не похоже, что вы используете противоположные функции в библиотеках OpenSSL. Это требует неприятностей, тем более что OpenSSL не так хорошо документирован. Например. он иногда использует определенные методы деривации ключей. Сначала попытайтесь совместить методы шифрования и дешифрования (например, запишите, какие функции OpenSSL вызывается из Ruby, а затем отмените их). –

ответ

1

А вот фиктивный пароль обратного вызова (не уверен цели этой функции, но я думаю, что это может вернуть длину пароля):

int pem_password_callback(char *buf, int max_len, int flag, void *pwd) 
{ 
    return 8; 
} 

Нет, это не фиктивный. В вашем примере вы только что вернули буфер с 8 символами нежелательной почты (что бы ни случилось в buf).

Обратный вызов с паролем - это то, где вы программно подключаете свой пароль. Вам предоставляется buff из max_len, и вам нужно скопировать пароль в буфер и вернуть количество копируемых байтов.

int pem_password_callback(char *buf, int max_len, int flag, void *ctx) 
{ 
    const char* PASSWD = "password"; 
    int len = strlen(PASSWD); 

    if(len > max_len) 
     return 0; 

    memcpy(buf, PASSWD, len); 
    return len; 
} 

flag это флаг чтения/записи для обозначения, если вы читаете ключ или записи ключа. На практике я никогда не использовал его.

Вы будете использовать его похожим на:

FILE* file = ...; 
EVP_PKEY* pkey = PEM_read_PrivateKey(file, NULL, pem_password_callback, NULL); 

В отличии от обычной записи (которая нуждается в EVP_* шифре), программа для чтения знает, что вы использовали для шифрования ключа с, поскольку его закодированным в закрытом ключе.

В моих системах, я на самом деле использовать контекст для лейбла, чтобы гарантировать, что одни и те же пароли прибывают в различных производных ключей:

EVP_PKEY* pkey = PEM_read_PrivateKey(file, NULL, pem_password_callback, "Some Context"); 

Затем, на мой пароль обратного вызова:

int pem_password_callback(char *buf, int max_len, int flag, void *ctx) 
{ 
    // "Some Context" in the example above 
    char* label = (char*)ctx; 

    // Hash password and label 
    // ... 

    // Copy hash to buffer, return length 
    ... 
} 
Смежные вопросы