PDA

Просмотр полной версии : RSADecrypt


supernewbie
04.08.2011, 01:59
Нужна помощь в написании RSADecrypt. для л2, на делфи, нашел пару алгоритмов в гугле но они принимают странно большое кол-во параметров, хз че им нада)

function RSAEncrypt(a,p,rsakey:string):string;
var
sD,sR,sM:string;
m,e,d,r:TFGInt;
begin
if length(a)>14 then setlength(a,14);
while length(a)<14 do a:=a+#0;
if length(p)>16 then setlength(p,16);
while length(p)<16 do p:=p+#0;
sD:=a+p+#0#0#0#0;
sM:=rsakey;
Base10StringToFGInt('65537',e);
Base256StringToFGInt(sD,d);
Base256StringToFGInt(sM,m);
FGIntMontgomeryModExp(d,e,m,r);
FGIntToBase256String(r,sR);
result:=sR;
end;

этот RSAEncrypt выглядит более понятнее и компактнее чем у этих ребят:
http://read.pudn.com/downloads64/sourcecode/crypt/224545/RSA/FGIntRSA.PAS__.htm
такой же RSADecrypt надыбать бы где-нить

xkor
04.08.2011, 02:31
вот от моего зачатка логин сервера линейки:
type
mpz_t = record
mp_alloc,
mp_size: Integer;
mp_d: Pointer;
end;
TRSAKey = record
p,q,e,n,d: mpz_t;
scrambled: array[0..127] of Byte;
end;
PRSAKey = ^TRSAKey;

const
gmpdll = 'libgmp-3.dll';

procedure mpz_init(var Dest: mpz_t); cdecl;
external gmpdll name '__gmpz_init';
procedure mpz_init_set_ui(var Dest: mpz_t; Src: Cardinal); cdecl;
external gmpdll name '__gmpz_init_set_ui';
procedure mpz_clear(var Dest: mpz_t); cdecl;
external gmpdll name '__gmpz_clear';
procedure mpz_powm(var Dest: mpz_t; const Base, Exponent, Modulus: mpz_t); cdecl;
external gmpdll name '__gmpz_powm';
procedure mpz_powm_ui(var Dest: mpz_t; var Base: mpz_t; Exponent: Cardinal;
const Modulus: mpz_t); cdecl;
external gmpdll name '__gmpz_powm_ui';
function mpz_probab_prime_p(var Src: mpz_t; Repetitions: Integer): Integer; cdecl;
external gmpdll name '__gmpz_probab_prime_p';
procedure mpz_add_ui(var Dest: mpz_t; var Src1: mpz_t; Src2: Cardinal); cdecl;
external gmpdll name '__gmpz_add_ui';
procedure mpz_random(var Dest: mpz_t; MaxSize: Integer); cdecl;
external gmpdll name '__gmpz_random';
procedure mpz_nextprime(var Dest: mpz_t; var Src: mpz_t); cdecl;
external gmpdll name '__gmpz_nextprime';
procedure mpz_mul(var Dest: mpz_t; var Src1, Src2: mpz_t); cdecl;
external gmpdll name '__gmpz_mul';
procedure mpz_sub_ui(var Dest: mpz_t; var Src1: mpz_t; Src2: Cardinal); cdecl;
external gmpdll name '__gmpz_sub_ui';
function mpz_invert(var Dest: mpz_t; var Src, Modulus: mpz_t): Integer; cdecl;
external gmpdll name '__gmpz_invert';
function mpz_get_str(Dest: PAnsiChar; Base: Integer; var Src: mpz_t): PAnsiChar; cdecl;
external gmpdll name '__gmpz_get_str';
procedure mpz_mul_ui(var Dest: mpz_t; var Src1: mpz_t; Src2: Cardinal); cdecl;
external gmpdll name '__gmpz_mul_ui';
procedure mpz_mul_si(var Dest: mpz_t; var Src1: mpz_t; Src2: Integer); cdecl;
external gmpdll name '__gmpz_mul_si';
procedure mpz_mod(var Dest: mpz_t; var Src1,Src2: mpz_t); cdecl;
external gmpdll name '__gmpz_mod';
function mpz_cmp_si(var Src1: mpz_t; Src2: Integer): Integer; cdecl;
external gmpdll name '__gmpz_cmp_si';
procedure mpz_cdiv_q(var Dest: mpz_t; var Src1, Src2: mpz_t); cdecl;
external gmpdll name '__gmpz_cdiv_q';
function mpz_size(var Src1: mpz_t): Integer; cdecl;
external gmpdll name '__gmpz_size';

procedure mpz_import(var rop: mpz_t; count, order, size, endian,
nails: Cardinal; const op); cdecl;
external gmpdll name '__gmpz_import';
procedure mpz_export(var rop, count; order, size, endian,
nails: Cardinal; const op: mpz_t); cdecl;
external gmpdll name '__gmpz_export';


// Функция проверяет, является ли число простым.
// Если нет, то делает таковым
procedure CheckForPrime(var p: mpz_t);
begin
while(mpz_probab_prime_p(p,64)=0) do
mpz_nextprime(p,p);
end;

// убирание извращений над публичной частью ключа
procedure deScrambleRSAKey(var raw);
var
ab: array[0..127] of Byte absolute raw;
i: Word;
b: Byte;
begin
for i:=0 to $3f do ab[$40+i]:=ab[$40+i] xor ab[i];
for i:=0 to $03 do ab[$0d+i]:=ab[$0d+i] xor ab[$34+i];
for i:=0 to $3f do ab[i]:=ab[i] xor ab[$40+i];
for i:=0 to $03 do begin
b:=ab[i];
ab[i]:=ab[$4d+i];
ab[$4d+i]:=b;
end;
end;

// извращения над публичной частью ключа
procedure ScrambleRSAKey(var raw);
var
ab: array[0..127] of Byte absolute raw;
i: Word;
b: Byte;
begin
for i:=0 to $03 do begin
b:=ab[i];
ab[i]:=ab[$4d+i];
ab[$4d+i]:=b;
end;
for i:=0 to $3f do ab[i]:=ab[i] xor ab[$40+i];
for i:=0 to $03 do ab[$0d+i]:=ab[$0d+i] xor ab[$34+i];
for i:=0 to $3f do ab[$40+i]:=ab[$40+i] xor ab[i];
end;

// генерация нового RSA ключа
function NewRSAKey: TRSAKey;
var
p_m,q_m,fi: mpz_t;
c: Cardinal;
begin
with Result do begin
mpz_init(p);
mpz_init(q);
mpz_init(e);
mpz_init(n);
mpz_init(d);

mpz_init(p_m);
mpz_init(q_m);
mpz_init(fi);

// 1. Выбираются два случайных простых числа p и q заданного размера
mpz_random(p,16);
CheckForPrime(p);
//mpz_init_set_ui(p,3557);

mpz_random(q,16);
CheckForPrime(q);
//mpz_init_set_ui(q,2579);

// 2. Вычисляется их произведение n=p*q
mpz_mul(n,p,q);

c:=32;
mpz_export(scrambled,c,1,4,1,0,n);
ScrambleRSAKey(scrambled);

// 3. Вычисляется значение функция Эйлера от числа n: fi=(p-1)(q-1)
mpz_sub_ui(p_m,p,1);
mpz_sub_ui(q_m,q,1);

mpz_mul(fi,q_m,p_m);

// 4. Выбирается целое число e, взаимно простое со значением функции Эйлера.
// Обычно в качестве e берут простые числа, содержащие небольшое количество
// единичных битов в двоичной записи, например, простые числа Ферма 17, 257,
// или 65537.
mpz_init_set_ui(e,65537);

// 5. Вычисляется число d мультипликативное обратное к числу e по модулю fi
mpz_invert(d, e, fi);

mpz_clear(p_m);
mpz_clear(q_m);
mpz_clear(fi);
end;
end;

// просто представление ключа в виде строки
function RSAKeyToStr(k: TRSAKey): string;
begin
Result:='p: '+mpz_get_str(nil,16,k.p)+sLineBreak+
'q: '+mpz_get_str(nil,16,k.q)+sLineBreak+
'e: '+mpz_get_str(nil,16,k.e)+sLineBreak+
'n: '+mpz_get_str(nil,16,k.n)+sLineBreak+
'd: '+mpz_get_str(nil,16,k.d);
end;

// дешифруем RSA блок
procedure RSA_BlockDec(var data; const k: TRSAKey; size: Cardinal = 128);
var
dt,r: mpz_t;
c: Cardinal;
begin
mpz_init(dt);
mpz_init(r);
mpz_import(dt,size,1,1,1,0,data);
mpz_powm(r,dt,k.d,k.n);
c:=1;
mpz_export(data,c,1,size,1,0,r);
mpz_clear(dt);
mpz_clear(r);
end;

// шифруем RSA блок
procedure RSA_BlockEnc(var data; const k: TRSAKey; size: Cardinal = 128);
var
dt,r: mpz_t;
c: Cardinal;
begin
mpz_init(dt);
mpz_init(r);
mpz_import(dt,size,1,1,1,0,data);
mpz_powm_ui(r,dt,65537,k.n);
c:=1;
mpz_export(data,c,1,size,1,0,r);
mpz_clear(dt);
mpz_clear(r);
end;
собсно тебе я так понимаю нужна от сюда RSA_BlockDec, и в параметре k: TRSAKey тебе надо заполнить только n (это модуль - публичная часть ключей передающаяся в извращенном виде в первом пакете от сервера) и d (это секретный ключ, который имеется лишь у сервера и потому только он может дешифровать ответ клиента)
поскольку секретный ключ знает только тот кто генерировал ключи я привёл код всего что нужно и для генерации ключей, ну и на всякий случай для приведения модуля к виду в котором его кидают клиенту и обратно.
ЗЫ libgmp-3.dll найдешь сам, это не проблема, даже подскажу что она используется в l2encdec и соответственна её можно скачать с ним от сюда http://dstuff.luftbrandzlung.org/l2.php

supernewbie
04.08.2011, 02:44
а почему зачатки?) почему бросил это дело?

xkor
04.08.2011, 02:55
supernewbie, я счас уже даже не помню с какой целью начинал)
Свой л2 сервак я писать вроде не собирался

Добавлено через 2 минуты
да и вообще у меня чтот большинство проектов начато и брошено в зачаточном состоянии, с доведением до конца у меня проблемы(

Yegor
04.08.2011, 13:12
supernewbie, xkor писал своего универсального бота, но вдруг почему то закрыл проект.

supernewbie
04.08.2011, 13:51
но тогда причем тут логин сервер O_o

xkor
04.08.2011, 14:34
Yegor, не, логин сервер я не для него писал, а бота я не вдруг закрыл, просто интерес и время очередной раз исчезли, а когда появились как то уже подзабыл что там у меня там как и поплыли опасные мысли очередной раз начать его переписывать глобально...
ЗЫ но я ещё питаю надежду что я его всётаки когда нибудь (желательно конечно до полной смерти линейки) доделаю)

supernewbie
04.08.2011, 18:49
не канает или так и должно быть?) вроде нет

xkor
04.08.2011, 20:30
supernewbie, вот так канает:
procedure TForm1.FormCreate(Sender: TObject);
var
key:TRSAKey;
s:String;

begin
s:=#0+Edit1.text;
key:=NewRSAKey;
RSA_BlockEnc(s[1],key);
RSA_BlockDec(s[1],key);
Delete(s,1,1);
Edit2.text:=s;
end;

суть в том что key.n должно быть большим числом нежели шифруемое, а для этого надо чтобы первый а лучше и ещё парочка следующих байт в шифруемом блоке были нулевыми
ЗЫ твой вариант кстати тоже один раз из где то 4-5 прокатывает)

supernewbie
04.08.2011, 21:08
ы, всё, лог и пасс из РеквестАутЛогин вычленен, можно пускать пинчи :diablo:
шутко

anonymice01
17.01.2012, 16:43
А подскажите есть ли хоть какой-то способ узнать
d (это секретный ключ, который имеется лишь у сервера и потому только он может дешифровать ответ клиента)
зная что передаем и все остальные ключи?

Статичен ли этот ключ?
сервер lineage2.com :)

Demion
17.01.2012, 17:08
Ключ не статичен, расшифровать не получится на стороне клиента не получится.

anonymice01
17.01.2012, 17:14
т.е. посмотреть что отправляет клиент/бот в RequestAuthLogin невозможно?

Demion
17.01.2012, 17:17
Когда я писал лоигн сервер / логин клиент, то посмотреть можно было только на сервере, потому что у клиента нет нужного ключа. Либо внедрятся в клиент и искать где он генерирует РСА блок (но как я понимаю тебе нужно из пакета узнать).

Yegor
17.01.2012, 18:55
Либо поднять свой логин сервер на основе какой нибудь java фришки и заставить клиент L2 пытаться конектиться к нему.
Или еще можно хукнуть функцию которая формирует этот пакет и посмотреть пакет до шифрации.

Demion
17.01.2012, 22:18
Я так и делал со своим сервером (изврат). Где-то на флешке валяются мои исходники на сях. В клиент есть функция (метод UNetworkHandler) - RequestAuthLogin(WCHAR* Login, WCHAR* Pass, INT i);
Но как я понял anonymice01 хочет узнать логин пароль из пакета.

anonymice01
17.01.2012, 23:05
Да все верно, хотел узнать из пакета.
Кстати, а rsa шифрация применяется только к логину-паролю или ко всему пакету?

Demion
17.01.2012, 23:06
Только в 128 байтовому блоку, где логин и пароль.