Нужна помощь в написании RSADecrypt. для л2, на делфи, нашел пару алгоритмов в гугле но они принимают странно большое кол-во параметров, хз че им нада)
Delphi Код:
function RSAEncrypt(a,p,rsakey:string):string;
var
sD,sR,sM:string;
m,e,d,r:TFGInt;
beginiflength(a)>14thensetlength(a,14);
whilelength(a)<14do a:=a+#0;
iflength(p)>16thensetlength(p,16);
whilelength(p)<16do 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;
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] ofByte;
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);
beginwhile(mpz_probab_prime_p(p,64)=0)do
mpz_nextprime(p,p);
end;
// убирание извращений над публичной частью ключаprocedure deScrambleRSAKey(var raw);
var
ab: array[0..127] ofByte absolute raw;
i: Word;
b: Byte;
beginfor i:=0to $3f do ab[$40+i]:=ab[$40+i] xor ab[i];
for i:=0to $03do ab[$0d+i]:=ab[$0d+i] xor ab[$34+i];
for i:=0to $3f do ab[i]:=ab[i] xor ab[$40+i];
for i:=0to $03dobegin
b:=ab[i];
ab[i]:=ab[$4d+i];
ab[$4d+i]:=b;
end;
end;
// извращения над публичной частью ключаprocedure ScrambleRSAKey(var raw);
var
ab: array[0..127] ofByte absolute raw;
i: Word;
b: Byte;
beginfor i:=0to $03dobegin
b:=ab[i];
ab[i]:=ab[$4d+i];
ab[$4d+i]:=b;
end;
for i:=0to $3f do ab[i]:=ab[i] xor ab[$40+i];
for i:=0to $03do ab[$0d+i]:=ab[$0d+i] xor ab[$34+i];
for i:=0to $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;
beginwith Result dobegin
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
__________________
Я здесь практически не появляюсь!, Skype - ikskor
Последний раз редактировалось xkor, 04.08.2011 в 02:38.
Yegor, не, логин сервер я не для него писал, а бота я не вдруг закрыл, просто интерес и время очередной раз исчезли, а когда появились как то уже подзабыл что там у меня там как и поплыли опасные мысли очередной раз начать его переписывать глобально...
ЗЫ но я ещё питаю надежду что я его всётаки когда нибудь (желательно конечно до полной смерти линейки) доделаю)
__________________
Я здесь практически не появляюсь!, Skype - ikskor
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 прокатывает)
__________________
Я здесь практически не появляюсь!, Skype - ikskor