PDA

Просмотр полной версии : Шифрование RSA


Blo0DeX
05.11.2009, 12:33
Доброго времени суток, подскажите компонент шифрования RSA для С Builder'a? Или разъясните в чем я неправ.

Из статьи с википедии (http://ru.wikipedia.org/wiki/RSA) следует что для того чтобы зашифровать пакет необходимы только N и E части ключа.

В статье TechnoWiz@rd'а (http://fursoffers.narod.ru/Packets.htm) написано:

Ключ состоит из следующих частей: B = 1024, E = 65537, N = передается в пакете Init. Вместе эти 3 части составляют целый RSA
ключ

Возникает вопрос: зачем нужно В?

Гуглом нарыл только одну библиотеку, реализующую RSA, в которой меня смутили передаваемые ей параметры


long RsaEncode(long b, long n, long e)
{
long result = 1;
for(long i=0; i<e; i++)
{
result = (result*b) % n;
}
return result;
}

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

xkor
05.11.2009, 15:07
Blo0DeX, что делает приведенная функция я не знаю но точно не шифрует по RSA 1024битным ключем
для реализации этого шифрования советую использовать библиотеку GMP, в нете есть примеры реализации РСА с её помощью, саму библиотеку лучше брать в виде libgmp-3.dll файла ибо там точно всё что надо экспортируется (она кстати в l2encdec используется)
ЗЫ очень быстрая либаб у меня с ней шифрование логина с паролем происходит в 20 раз быстрее чем если юзать FGInt модуль для дельфиб причем и работает всегда правильно в отличии от всё того же FGInt

Blo0DeX
06.11.2009, 13:27
xkor, насколько я понял В используется только для обозначения длины ключа...
Про GMP я уже читал и на этом форуме и на олчитс, но не мог никак выбрать нужные мне функции, в итоге скачал исходники GMP и там уже все нашел.

mpz_inp_str(dest_integer, stream, base) -- Input a number in base BASE from stdio stream STREAM and store the result in DEST_INTEGER.
#define mpz_inp_str __gmpz_inp_str
__GMP_DECLSPEC size_t mpz_inp_str __GMP_PROTO ((mpz_ptr, FILE *, int));

mpz_powm(res,base,exp,mod) -- Set RES to (base**exp) mod MOD.
#define mpz_powm __gmpz_powm
__GMP_DECLSPEC void mpz_powm __GMP_PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr));

mpz_out_str(stream, base, integer) -- Output to STREAM the multi prec. integer INTEGER in base BASE.
#define mpz_out_str __gmpz_out_str
__GMP_DECLSPEC size_t mpz_out_str __GMP_PROTO ((FILE *, int, mpz_srcptr));


И если я все правильно понял, то должно получиться примерно сследующее:

void RSA_Encrypt(char *packet,char *RSAKey)
{
char *string_to_encrypt;
memcpy(string_to_encrypt,packet+2,128); //необходимо зашифровать только 128 байт начиная с 3

mpz_t Pa,raw,n,e;
mpz_init(Pa);
mpz_init(raw);
mpz_init(n);
mpz_init(e);

mpz_inp_str(raw,string_to_encode,16);
mpz_inp_str(n,RSAKey,16);
mpz_inp_str(e,"65537",10);

mpz_powm(
Pa, // рез-т
raw, // основание (т.е. блок, который необходимо зашифровать)
e, //65537
n); //из пакета инит

mpz_out_str(
string_to_encrypt,
16,
Pa);
memcpy(packet+2,string_to_encrypt,128); //запихиваем в пакет зашифрованный блок
}

xkor
06.11.2009, 21:44
Blo0DeX, ну да, как то так, ток не забудь что RSAKey приходит в зашифрованном виде
PS и кстати у mpz_powm есть аналог (mpz_powm_i вроде или чтот в таком духе) для случаев когда e является небольшим числом, а у нас какраз такой случай, этот аналог думаю удобнее и наверно чуть быстрее

Blo0DeX
06.11.2009, 21:58
PS и кстати у mpz_powm есть аналог (mpz_powm_i вроде или чтот в таком духе) для случаев когда e является небольшим числом есть mpz_powm_ui, в описании то же самое что и у mpz_powm, что на самом деле не ковырялся, не смотрел....

xkor
07.11.2009, 00:25
Blo0DeX, ну она и делает то же самое, отличается тока типом одного из параметров

Кислый
12.11.2010, 18:50
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmp.h>

int main (int argc, char **argv)
{
//var
char rsakey[16] = {'1','1','2','3','4','5','6','7','8','9','A','B',' C','D','E','F'};
char* pack = "123AAA45";
printf("pack = %s\n",pack);
printf("rsakey = %s\n",rsakey);

//begin*
// инициализация переменных
mpz_t m, e, d, r;
mpz_init(m);
mpz_init(e);
mpz_init(d);
mpz_init(r);


mpz_init_set_str(m, rsakey, 16);
mpz_init_set_str(d, pack, 16);
//mpz_set_ui(e,65537); один хер.
mpz_init_set_str(e, "65537", 10);
mpz_powm(r, d, e, m);

//mpz_get_str(sR, 16, r);
//char* sR = mpz_get_str(NULL, 16, d);

char sR[5000] = {};
mpz_get_str(sR, 16, r);
int k = strlen(sR);

printf("результат = %s | размер %i\n",sR, k);

mpz_clear(m);
mpz_clear(e);
mpz_clear(d);
mpz_clear(r);
printf("Finish\n");
return 100500; //стопицот
}

xkor
13.11.2010, 00:22
Кислый, это ты к чему решил воскресить прошлогоднюю тему?

Кислый
13.11.2010, 13:32
да к тому, что она послужила для меня отправной точкой в поиске решения ))
в принципе код рабочий, но смущает вот что: pack и rsakey должны состаять из символов 16й системы счисления.. (т.е. {'0','1','2','3','4','5','6','7','8','9','A','B',' C','D','E','F'};).

является ли это затруднением ?
учитывая что pack - это 132 байта. при этом как минимум 30 байт (логин и пасс ) могут содержать другие символы

xkor
13.11.2010, 14:36
pack и rsakey должны состаять из символов 16й системы счислениякому они это должны?

Кислый
13.11.2010, 16:56
приведенному мною коду:rolleyes:

pack = 123AAA45M
rsakey = 1123456789ABCDEF
результат = 0 | размер 1
F


pack = 123AAA45F
rsakey = 1123456789ABCDEF
результат = 100ef4fc65feff86 | размер 16
F


Добавлено через 1 час 1 минуту
xkor,
какие функции ты использовал ?
у меня мысть уже была организовать перевод str2hex, но это повлечет за собой необоснованное увеличение длинны pack

была мысль

Добавлено через 1 минуту
была мысль выставить base = 256, но выдает на гора ошибку :Исключение в операции с плавающей точкой

xkor
13.11.2010, 18:01
Кислый, у меня так:function RSAEncrypt_GMP(login, psw: AnsiString; var rsakey): TBytes;
var
sD: AnsiString;
m,d,r: mpz_t;
count: Integer;
begin
RSAkeyDecode(rsakey);
if length(login)>14 then setlength(login,14);
while length(login)<14 do login:=login+#0;
if length(psw)>16 then setlength(psw,16);
while length(psw)<16 do psw:=psw+#0;
sD:=#$24#0#0+login+psw+#0#0#0#0;
mpz_init(m);
mpz_import(m,128,1,1,0,0,rsakey);
mpz_init(d);
mpz_import(d,Length(sD),1,1,0,0,sD[1]);
mpz_init(r);
mpz_powm_ui(r,d,65537,m);
count:=32;
SetLength(Result,128);
mpz_export(Result[0],count,1,4,1,0,r);
mpz_clear(r);
mpz_clear(d);
mpz_clear(m);
end;

Кислый
13.11.2010, 22:47
Ггг

и работает ?

Добавлено через 2 часа 0 минут
у меня просто твой код запарывается на mpz_export(Result[0],count,1,4,1,0,r);
мегешь обьяснить почему ты именно эти аргументы пердаешь ?

xkor
13.11.2010, 23:04
Кислый, работет, не первый год, а почему должны быть не эти аргументы?)
можно в принципе count сделать не 32 а 128 и вместо 4 написать 1, но тогда если старший байт будет нулевым, что весьма вероятно, то Result будет в 256 раз больше чем должно)

Кислый
13.11.2010, 23:18
блин. у меня на этой строчке в си Ошибка сегментации ))
попробовал заменить на mpz_out_str(stdout, 32, r);
1 ) можешь описать назначение аргументов ? видимо я что-то не так понял..
2 ) снял лог функции RSAEncrypt в файл:
pack: maxno 123 (туча нулей не отображается тут)
sR : џ^g"8kъЫ
+qГ1˜zбИ=oбw°ч,ЪOS%A“й<®/Ї^˜;ќ§’fѕ8‰9њњц\PЅ™?}Щ$р *љlBСew53EMаY•Dе_8«V<¦Q ¦…‹„ЭІФЅѓЈ2ђaз4…юЋnЏъ(…Ч.№
у меня же mpz_out_str выдает керовину

xkor
13.11.2010, 23:31
procedure mpz_export(var rop, count; order, size, endian, nails: Cardinal; const op: mpz_t); cdecl;
rop - то куда экспортируем
count - сколько элементов импортируем
order - порядок экспорта (0 - от младшего к старшему, 1 - наоборот)
size - размер элемента в байтах
endian - порядок байт в элементах (как и order)
nails - а хер его знает, не помню...
op - откуда экспортируем

то есть я экспортирую в 128мибайтный результат (Result) 128байтное число (r) в виде 32ух 4хбайтных элементов от старшего байта к младшему)

у меня же mpz_out_str выдает керовинуи в чем херовиность? что ты его просишь выдать то и выдаёт...

Кислый
13.11.2010, 23:43
kisly@kisly-desktop:~$ ./1234 MAXNI MAXNO
pack = MAXNI
rsakey = MAXNO

result = 9di3k1r6vd285o4h

Добавлено через 1 минуту
и чем отличается mpz_out_str от mpz_export ?

Добавлено через 1 минуту
и в чем херовиность?
в размере..
видимо я не ту функцию прошу.. )))

xkor
14.11.2010, 00:31
и чем отличается mpz_out_str от mpz_export
mpz_out_str переводит число в строку в заданной системе счисления (причем 256ричная система не поддерживается)
mpz_export экспортирует число в память в бинарном виде
так что я хз чем они вообще похожи
а ещё я хз чего ты вообще пытаешь сделать, явно не авторизоваться на сервере линейки

Кислый
14.11.2010, 00:35
ну что ж так сразу)) ну я еще только учусь.. просто англ. плохо понимаю

xkor
14.11.2010, 01:22
просто англ. плохо понимаюа английский то тут вообще где?

guplen
14.11.2010, 01:45
Кислый, юзай FGint, ксор напугал тебя, сказав что он ошибается и работает в 20 раз медленней. Я думаю ты не пишешь высокопроизводительный эмулятор сервера линейки и тебе хватит фгинта. На счет ошибок не знаю, при мне не ошибался :)

Я писал эмулятор логин-сервера и прогу для захода чаром на сервер, везде использовал FGint и не подводило вроде бы.

Скорей всего ФГинт ошибается при генерировании простого числа и врятли при возведении в степень.

xkor
14.11.2010, 02:04
guplen, FGInt вообщет только на дельфи есть, а Кислый, как я понял на C++ пишет)

Кислый
14.11.2010, 11:11
в мануалах. если бы я их нормально мог читатьЮ я бы не задалбывал кучей вопросов