Просмотр полной версии : Шифрование RSA
Доброго времени суток, подскажите компонент шифрования 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;
}
Из этого кода можно сделать вывод, что в эту функцию передаются только части ключа, а как тогда скормить ей строку, которую необходимо зашифровать?
Blo0DeX, что делает приведенная функция я не знаю но точно не шифрует по RSA 1024битным ключем
для реализации этого шифрования советую использовать библиотеку GMP, в нете есть примеры реализации РСА с её помощью, саму библиотеку лучше брать в виде libgmp-3.dll файла ибо там точно всё что надо экспортируется (она кстати в l2encdec используется)
ЗЫ очень быстрая либаб у меня с ней шифрование логина с паролем происходит в 20 раз быстрее чем если юзать FGInt модуль для дельфиб причем и работает всегда правильно в отличии от всё того же FGInt
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); //запихиваем в пакет зашифрованный блок
}
Blo0DeX, ну да, как то так, ток не забудь что RSAKey приходит в зашифрованном виде
PS и кстати у mpz_powm есть аналог (mpz_powm_i вроде или чтот в таком духе) для случаев когда e является небольшим числом, а у нас какраз такой случай, этот аналог думаю удобнее и наверно чуть быстрее
PS и кстати у mpz_powm есть аналог (mpz_powm_i вроде или чтот в таком духе) для случаев когда e является небольшим числом есть mpz_powm_ui, в описании то же самое что и у mpz_powm, что на самом деле не ковырялся, не смотрел....
Blo0DeX, ну она и делает то же самое, отличается тока типом одного из параметров
#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; //стопицот
}
Кислый, это ты к чему решил воскресить прошлогоднюю тему?
да к тому, что она послужила для меня отправной точкой в поиске решения ))
в принципе код рабочий, но смущает вот что: pack и rsakey должны состаять из символов 16й системы счисления.. (т.е. {'0','1','2','3','4','5','6','7','8','9','A','B',' C','D','E','F'};).
является ли это затруднением ?
учитывая что pack - это 132 байта. при этом как минимум 30 байт (логин и пасс ) могут содержать другие символы
pack и rsakey должны состаять из символов 16й системы счислениякому они это должны?
приведенному мною коду:rolleyes:
pack = 123AAA45M
rsakey = 1123456789ABCDEF
результат = 0 | размер 1
F
pack = 123AAA45F
rsakey = 1123456789ABCDEF
результат = 100ef4fc65feff86 | размер 16
F
Добавлено через 1 час 1 минуту
xkor,
какие функции ты использовал ?
у меня мысть уже была организовать перевод str2hex, но это повлечет за собой необоснованное увеличение длинны pack
была мысль
Добавлено через 1 минуту
была мысль выставить base = 256, но выдает на гора ошибку :Исключение в операции с плавающей точкой
Кислый, у меня так: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;
Ггг
и работает ?
Добавлено через 2 часа 0 минут
у меня просто твой код запарывается на mpz_export(Result[0],count,1,4,1,0,r);
мегешь обьяснить почему ты именно эти аргументы пердаешь ?
Кислый, работет, не первый год, а почему должны быть не эти аргументы?)
можно в принципе count сделать не 32 а 128 и вместо 4 написать 1, но тогда если старший байт будет нулевым, что весьма вероятно, то Result будет в 256 раз больше чем должно)
блин. у меня на этой строчке в си Ошибка сегментации ))
попробовал заменить на 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 выдает керовину
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 выдает керовинуи в чем херовиность? что ты его просишь выдать то и выдаёт...
kisly@kisly-desktop:~$ ./1234 MAXNI MAXNO
pack = MAXNI
rsakey = MAXNO
result = 9di3k1r6vd285o4h
Добавлено через 1 минуту
и чем отличается mpz_out_str от mpz_export ?
Добавлено через 1 минуту
и в чем херовиность?
в размере..
видимо я не ту функцию прошу.. )))
и чем отличается mpz_out_str от mpz_export
mpz_out_str переводит число в строку в заданной системе счисления (причем 256ричная система не поддерживается)
mpz_export экспортирует число в память в бинарном виде
так что я хз чем они вообще похожи
а ещё я хз чего ты вообще пытаешь сделать, явно не авторизоваться на сервере линейки
ну что ж так сразу)) ну я еще только учусь.. просто англ. плохо понимаю
просто англ. плохо понимаюа английский то тут вообще где?
Кислый, юзай FGint, ксор напугал тебя, сказав что он ошибается и работает в 20 раз медленней. Я думаю ты не пишешь высокопроизводительный эмулятор сервера линейки и тебе хватит фгинта. На счет ошибок не знаю, при мне не ошибался :)
Я писал эмулятор логин-сервера и прогу для захода чаром на сервер, везде использовал FGint и не подводило вроде бы.
Скорей всего ФГинт ошибается при генерировании простого числа и врятли при возведении в степень.
guplen, FGInt вообщет только на дельфи есть, а Кислый, как я понял на C++ пишет)
в мануалах. если бы я их нормально мог читатьЮ я бы не задалбывал кучей вопросов
vBulletin® v3.6.11, Copyright ©2000-2024, Jelsoft Enterprises Ltd. Перевод: zCarot