Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« : 03-09-2019 13:19 » |
|
пытаюсь при помощи библиотеки OpenSSL сгенерить открытый и закрытый ключи RSA вот такой код, найденный в интернете, позволяет сохранить ключи в файлы RSA* rsa=0; BIGNUM* bignum=0; BIO* bp_public=0; BIO* bp_private=0; do { int ret = 0; int bits = 2048; unsigned long e = RSA_F4;
// 1. generate rsa key bignum = BN_new(); ret = BN_set_word(bignum,e); if(ret != 1)break;
rsa = RSA_new(); ret = RSA_generate_key_ex(rsa, bits, bignum, 0); if(ret != 1)break;
// 2. save public key bp_public = BIO_new_file("public.pem", "w+"); ret = PEM_write_bio_RSAPublicKey(bp_public, rsa); if(ret != 1)break;
// 3. save private key bp_private = BIO_new_file("private.pem", "w+"); ret = PEM_write_bio_RSAPrivateKey(bp_private, rsa, NULL, NULL, 0, NULL, NULL); if(ret != 1)break;
int iii=1; }while(0);
// 4. free if(bp_public )BIO_free_all(bp_public); if(bp_private)BIO_free_all(bp_private); if(rsa )RSA_free (rsa); if(bignum )BN_free (bignum); но как это всё сделать без использования файлов, сразу в буфер в памяти - никак не могу сообразить. Исходники библиотеки дичайшие (несмотря на обновление аж в 2018 году). Документация под стать. Подскажите, как напрямую в память сохранить ключи Добавлено через 44 секунды:как вариант - подскажите более вменяемую библиотеку/реализацию для c++
|
|
« Последнее редактирование: 03-09-2019 13:19 от Алексей1153 »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #1 : 03-09-2019 21:39 » |
|
В доке есть: BIO *mem = BIO_new(BIO_s_mem()); попробуй...
EXAMPLE Create a memory BIO and write some data to it:
BIO *mem = BIO_new(BIO_s_mem()); BIO_puts(mem, "Hello World\n");
Create a read only memory BIO:
char data[] = "Hello World"; BIO *mem; mem = BIO_new_mem_buf(data, -1);
Extract the BUF_MEM structure from a memory BIO and then free up the BIO:
BUF_MEM *bptr; BIO_get_mem_ptr(mem, &bptr); BIO_set_close(mem, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */ BIO_free(mem);
|
|
« Последнее редактирование: 03-09-2019 21:41 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 04-09-2019 03:39 » |
|
Ром, спасибо, теперь разобрался ) Вот вариант, где есть сохранение и в файл, и в вектор. Результаты идентичные RSA* rsa=0; BIGNUM* bignum=0;
std::vector<char> key_public; std::vector<char> key_private; do { const int bits=2048; const BN_ULONG e = RSA_F4; int result=0;
//генерация ключей, заполнение структуры RSA bignum = BN_new(); result = BN_set_word(bignum,e); if(result != 1)break;
rsa = RSA_new(); result = RSA_generate_key_ex(rsa, bits, bignum, 0); if(result != 1)break;
//сохранение в файлы { //public if(BIO* file=BIO_new_file("public.pem", "w+")) { result=PEM_write_bio_RSAPublicKey(file, rsa); if(result != 1) { //файл не создан } BIO_free_all(file ); }
//private if(BIO* file=BIO_new_file("private.pem", "w+")) { result=PEM_write_bio_RSAPrivateKey(file, rsa, 0, 0, 0, 0, 0); if(result != 1) { //файл не создан } BIO_free_all(file); } }
//сохранение в память { //public { BIO* memo=BIO_new(BIO_s_mem()); result = PEM_write_bio_RSAPublicKey(memo, rsa); if(result != 1) { //не удалось записать в память BIO_free(memo); } else { BUF_MEM* bufptr=0; BIO_get_mem_ptr(memo, &bufptr); BIO_set_close(memo, BIO_NOCLOSE); BIO_free(memo);
if(bufptr->length && bufptr->data) { key_public.assign(bufptr->data,bufptr->data+bufptr->length); }
BUF_MEM_free(bufptr); }
}
//private { BIO* memo=BIO_new(BIO_s_mem()); result = PEM_write_bio_RSAPrivateKey(memo, rsa, 0, 0, 0, 0, 0); if(result != 1) { //не удалось записать в память BIO_free(memo); } else { BUF_MEM* bufptr=0; BIO_get_mem_ptr(memo, &bufptr); BIO_set_close(memo, BIO_NOCLOSE); BIO_free(memo);
if(bufptr->length && bufptr->data) { key_private.assign(bufptr->data,bufptr->data+bufptr->length); }
BUF_MEM_free(bufptr); } } }
int iii=1; }while(0);
//чистка выделенной памяти if(rsa )RSA_free (rsa );rsa=0; if(bignum )BN_free (bignum);bignum=0;
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 04-09-2019 08:40 » |
|
допустим, ключи создавалиь с битностью 2048
а правильно ли я понимаю, что данные, скажем, длиной 259 байтов, одним блоком не шифруются, а разбиваются на блоки кратно значению (256-42)==(RSA_size()-paddingsize)==214 байта, и каждый блок на выходе даёт зашифрованный блок размером 256 ?
При раскодировании всё в обратном порядке - берём по 256, расшифровываем и складываем по <=214 байтов в результат
По крайней мере, я так попробовал - получилось (в том смысле, что то, что закодировал, идентично тому, что потом раскодировалось).
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 04-09-2019 14:51 » |
|
в общем, сумел разобраться со следующими моментами : - генерация ключей (кстати, то, что я привёл выше, правильно только для приватного ключа. Публичный нужно сохранять функцией PEM_write_bio_PUBKEY, а не PEM_write_bio_RSAPublicKey. Иначе публичный выходит кривой.) - расшифровка приватным ключом (удалённая сторона зашифровала данные публичным) не осилил: - шифрование публичным ключом (пока что это мою задачу не тормозит, поэтому не критично) -------------------------------- удивляет дикость интерфейса openssl, как-будто это всё было написано лет 20 назад энтузиастом С (без плюсов). Удивляет пустота документации. Там просто перечислены функции и кратно рассказано о параметрах. По этим докам ничего не слепливается, либо нужно много много рыть интернет, а также подключать метод научного тыка Если бы в тех же доках были бы просто живые примеры, как из этих кубиков сделать нужное действие, было бы уже терпимо. Но, увы ( Альтернативу кто-нибудь знает ?
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #5 : 04-09-2019 19:15 » |
|
Шифруешь приватным ключем? Это называют подписью. Для шифрования приватым ключем, обычно, сперва вычисляют хеш, который и шифруют. Хеш имеет фиксированную длину и непредсказуемые байты в составе, это, с одной стороны, упрощает задачу, с другой стороны, повышает стойкость. Если ты хочешь восстановить потом данные, то да, придется либо брать больший ключ, либо шифровать кусками. Шифрование публичным ключем принимает буфер любой длины, если не ошибаюсь. Ошибаюсь.
В доке все описано. https://www.openssl.org/docs/man1.1.1/man3/RSA_public_encrypt.htmlДля каждого режима заполнения указаны предельные размеры шифруемых данных. Заметь, используется RSA_size для определения базового размера, не надо высчитывать руками, чревато неприметными ошибками. У тебя какая версия OpenSSL? Кстати, какая цель шифрования?
|
|
« Последнее редактирование: 04-09-2019 21:43 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 05-09-2019 03:58 » |
|
RXL, шифрую публичным. В данный момент не шифрую, не сумел загрузить ключ, созданный PEM_write_bio_PUBKEY, в структуру RSA (если ключ создан PEM_write_bio_RSAPublicKey, то загрузить получается, но тогда ключ кривой). RSA_size - использую, ага (и ещё 42 байта для RSA_PKCS1_OAEP_PADDING нужно отнимать от этого значения)
версия не последняя, где именно посмотреть - не знаю. Вот думаю, может закачать новые версии файлов, может, там всё будет иначе. На досуге надо попробовать
цель шифрования - отдаю на ту сторону публичный ключ, мне приходит зашифрованный блок данных, раскрываю приватным
|
|
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #7 : 05-09-2019 06:55 » |
|
Как вариант - попробуйте посмотреть в сторону GNU TLS, если подходит лицензия. Если я правильно понял, то она тоже должна уметь нечто подобное.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 06-09-2019 04:54 » |
|
darkelf, спасибо, посмотрю. А что там с лицензией?
|
|
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #9 : 06-09-2019 05:22 » |
|
LGPL (в принципе не страшно) и GPL
|
|
|
Записан
|
|
|
|
|