Skip to content
La2Base
Home
DownloadsWikiForumFAQ
Search
ruen
Sign up Login
HomeFilesWikiLogin
  • Home
  • Downloads
  • Wiki
  • FAQ
  • Contact Us
  • About
  • Rules
  • Privacy
  • Terms of Service

© 2026 la2base.com · All rights reserved

ruen
Forum/Форум для новичков[JAVA]/[question] Rsa
Search

[question] Rsa

14 replies263 viewsCurrently viewing: 1
N
nuit

User

Участник

Posts: 79

На форуме с: 05/02/2008

Репутация: +19

Рейтинг: 0

· 05/06/2009, 04:32 PM

сборки: l2jserver, l2jfree (остальные просто не смотрел)
В чём смысл создания 10 keypair'ов ? Какой-то вид защиты от нубоботов, которые будут пугаться при виде новых публичных ключей? Или я чего-то недопонимаю?

0
eeee
eeee

User

Участник

Posts: 49

На форуме с: 09/26/2007

Репутация: +4

Рейтинг: 0

· 05/06/2009, 05:05 PM

оно тебе сильно мешает? crazy.gif

0
N
nuit

User

Участник

Posts: 79

На форуме с: 05/02/2008

Репутация: +19

Рейтинг: 0

· 05/06/2009, 05:15 PM

Ну у меня сейчас цель вычистить всё то что там наделали гореразработчики.. Может здесь кто подскажет что двигало человеком, который добавлял rsa.. Ато вдруг это что-то важное(вот только я даже не могу представить зачем это могло понадобиться) :)

0
eeee
eeee

User

Участник

Posts: 49

На форуме с: 09/26/2007

Репутация: +4

Рейтинг: 0

· 05/06/2009, 05:31 PM

ну горе не горе... но сделали они много)))

зачем эти ключи я тоже незнаю...

0
N
nuit

User

Участник

Posts: 79

На форуме с: 05/02/2008

Репутация: +19

Рейтинг: 0

· 05/06/2009, 05:36 PM

Цитата
зачем эти ключи я тоже незнаю...

Зачем одна пара я понимаю, но 10 :)

0
eeee
eeee

User

Участник

Posts: 49

На форуме с: 09/26/2007

Репутация: +4

Рейтинг: 0

· 05/06/2009, 05:41 PM

Цитата
Зачем одна пара я понимаю, но 10 :)


мания величия 0_О 05e811906ebf.gif

0
Игорь
Игорь

User

Новичок

Posts: 10

На форуме с: 05/05/2007

Репутация: +8

Рейтинг: 0

· 05/06/2009, 08:43 PM

RSA шифрует пакет RequestAuthLogin.Для каждого клиента - своя пара.Почему же их 10 ? Ну,судя по описанию,как только возникает надобность,одна из пар обновляется.Что же касается защиты,то прироста это не даст.Взять в пример тот же RequestAuthLogin,пакет от клиента,в котором передаются логин и пароль (самый защищённый crazy.gif ).Принцип прост : перехватываем пакет Init,пришедший от сервера,зная статический ключ BlowFish расшифровываем пакет,полученный результат - пакет,зашифрованный XOR'ом,т.е. ключ шифра в конце пакета.Расшифровав во второй раз (в надобности этого действия не уверен) мы изымаем из него публичный ключ RSA и динамический (для каждого клиента генерируется свой) ключ BlowFish,которым будут шифроваться все остальные пакеты.Далее ловим пакет RequestAuthLogin (от клиента) и сталкиваемся с основной проблемой : перед отсылкой пакета,клиент его шифрует публичным ключом RSA,который мы уже знаем.Но чтобы расшифровать закриптованный пакет - нужен секретный ключ,вторая часть пары.А он хранится на сервере.Вот для этого и нужно много обновляющихся пар.Так что логин и пасс остаются в сохранности pogranichnik.gif А все остальные пакеты можно расшифровать также как и Init,только используя второй,динамический ключ BlowFish.

З.Ы. В точности не уверен,ибо изложил как знаю/понимаю.Надеюсь ты понял значимость RSA smile3.gif Кстати,а чего в итоге ты хочешь добиться этой чисткой ?

0
N
nuit

User

Участник

Posts: 79

На форуме с: 05/02/2008

Репутация: +19

Рейтинг: 0

· 05/07/2009, 02:53 AM

Цитата
Для каждого клиента - своя пара

В этом нет никакого смысла, взять тот же https(ssl соединения), представь что еслиб на каждое соединение требовалось генерировать новую пару - не слишком ли трудоёмкий процесс(лет 5 назад на стареньких компах даже Сишные реализации делали это за 1-5 секунд), так и задосить не проблема :)
Процесс ведь обычно прост и это объясняют ещё в школе :)
1. соединение с сервером
2. сервер отдаёт публичный ключ(его можно никак не скрывать/прятать итп)
3. клиент генерируют ключ для симметричного шифрования(twofish в ла2)
4. шифрует twofish ключ публичным ключём и передаёт его на сервер
5. всё - клиент/сервер могут спокойно общаться, используя более производительную симметричную схему(twofish ключ у нас не перехватили - слава асиметричной криптографии)

Цитата
Надеюсь ты понял значимость RSA

Всё равно не понял зачем нужно 10 пар, ведь публичный ключ на то и публичный, что его можно и не скрывать(Я бы вообще один раз генерировал пару и при запуске постояно её и использовал). И если его узнают, то ничего расшифровать всё равно не смогут. Публичным ключём только происходит энкрипт, обратного процесса им не сделать..

Цитата
Кстати,а чего в итоге ты хочешь добиться этой чисткой ?

производительности (ну в большинстве мест - это смена алгоритмов), но шаманство с с асиметричной криптографией меня просто убило :)

0
N
nuit

User

Участник

Posts: 79

На форуме с: 05/02/2008

Репутация: +19

Рейтинг: 0

· 05/07/2009, 02:49 PM

что-то мне их криптография совсем мозг взрывает, массив из 20 симметричных ключей(Blowfish) для чего :) После пары сотен соединений я смогу собрать весь этот массив ключей. Хотя вероятность того что смогу с ними что-то сделать мала, но сам принцип того что есть какой-то постоянный пул для симметричных ключей - какой-то бред..

0
Игорь
Игорь

User

Новичок

Posts: 10

На форуме с: 05/05/2007

Репутация: +8

Рейтинг: 0

· 05/07/2009, 03:35 PM

Это бессмысленно,но синтаксически допустимо grin.gif Хотя смысл здесь какой-то должен быть.Вернёмся к https.В своё время я увлекался созданием "самопальных сертификатов" ) В одной статье было пояснение о том,что секретный ключ надо держать "за семью печатями",ибо в случае компроментации все соединения окажутся незащищёнными.Но здесь другая концепция,такого не может произойти.Во-первых даже одна пара генерируется,так что при каждом запуске пара ключей будет другой (и не исключено,что при надобности будет обновляться) :) Во-вторых кого волнует,вскроют ли пакет ? 20 ключей BlowFish - опять же иммитация (именно она) генерации динамического ключа.Ведь одно дело,когда ключ генерируется,а другое - когда из небольшого массива случайно выбирается.Да,пусть они и обновляются,но всё же.

Обычно как всё происходит - для каждого сокета имеется свой ключ селекции,у которого аттач - объект класса L2LoginClient.И для каждого такого объекта - полагается случайный ключ из массива (как RSA,так и BF).И знаете,пожалуй вы правы.Секретные ключи как были,так и останутся на сервере,так что эта "динамика" может идти лесом =) Честно говоря мне как-то и не приходила идея сократить ключи до одного.Блин,кажется одно и тоже написал дважды,но смысл думаю ясен smile3.gif

З.Ы. 2nuit,а вы случайно не зарегестрированы под этим же ником на aion-emu ? )

0
N
nuit

User

Участник

Posts: 79

На форуме с: 05/02/2008

Репутация: +19

Рейтинг: 0

· 05/07/2009, 04:16 PM

Цитата
В одной статье было пояснение о том,что секретный ключ надо держать "за семью печатями"

Если злоумышленик как-то доберётся до приватного ключа, то там уже скорее всего сможет просто всю базу утащить :)

Цитата
Ведь одно дело,когда ключ генерируется,а другое - когда из небольшого массива случайно выбирается

Код
/* l2jserver */
private void generateBlowFishKeys() {
  ...
  for (int j = 0; j < _blowfishKeys[i].length; j++) {
    _blowfishKeys[i][j] = (byte) (Rnd.nextInt(255)+1);
  }
  ...
}

это не новый рса ключ сделать :)
был бы толк еслиб они хранили в пуле ещё и S-boxes - 4096bytes, P-array - 72bytes(_http://en.wikipedia.org/wiki/Blowfish_(cipher)).. но они всё равно потом начинают выполнять более трудоёмкую задачу и генерировать их для каждого нового клиента(происходит ещё и дублирование данных), чтобы пользовать blowfish :)

Цитата
2nuit,а вы случайно не зарегестрированы под этим же ником на aion-emu

зарегистрирован


UPDATE:
Всё ещё хуже чем я думал :D на каждого клиента создаётся два Blowfish engine - один для шифрования, другой для расшифровки(это влияет на единственный парметр - private boolean encrypting).. и отличаются они только в исполнении функции processBlock
Код
if (encrypting) {
  encryptBlock(in, inOff, out, outOff);
} else {
  decryptBlock(in, inOff, out, outOff);
}

Вот что значит тру интерфейсы - вместо того чтобы сделать публичными энкрипт и декрипт, тру поцаны создают два крупных объекта :D Зато 20 ключей, которые генерятся быстрее чем 1 кэш-мисс - надо складывать в пул...
Вы ещё удивляетесь почему l2j серваки тормозят?! Всё же это не из-за жавы...

0
Игорь
Игорь

User

Новичок

Posts: 10

На форуме с: 05/05/2007

Репутация: +8

Рейтинг: 0

· 05/07/2009, 08:08 PM

Ну тогда наверно лучше сделать синглтон или вообще статические методы.Просто тому,кто это писал было проще сделать экземплярный вариант.Хмм,посидел немного и смастерил вот это blush2.gif :

Раскрывающийся текст

//====================================
// Useful constants
//====================================
private static final int ROUNDS = 16;
private static final int BLOCK_SIZE = 8; // bytes = 64 bits
private static final int SBOX_SK = 256;
private static final int P_SZ = ROUNDS + 2;

public String getAlgorithmName()
{
return "Blowfish";
}

public static final int processBlock(byte[] in, int inOff, byte[] out, int outOff, boolean encrypting, byte[] key) throws IOException
{
if (key == null)
throw new IllegalStateException("Blowfish not initialised");
if ((inOff + BLOCK_SIZE) > in.length)
throw new IOException("input buffer too short");
if ((outOff + BLOCK_SIZE) > out.length)
throw new IOException("output buffer too short");
if (encrypting)
encryptBlock(in, inOff, out, outOff, key);
else
decryptBlock(in, inOff, out, outOff, key);
return BLOCK_SIZE;
}

public void reset()
{
}

public static int getBlockSize()
{
return BLOCK_SIZE;
}

//==================================
// Private Implementation
//==================================
private static int F(int x, int[] S0, int[] S1, int[] S2, int[] S3)
{
return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff]) ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]);
}

/**
* apply the encryption cycle to each value pair in the table.
*/
private static void processTable(int xl, int xr, int[] table, int[] S0, int[] S1, int[] S2, int[] S3, int[] P)
{
int size = table.length;
for (int s = 0; s < size; s += 2)
{
xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2)
{
xr ^= F(xl, S0, S1, S2, S3) ^ P[i];
xl ^= F(xr, S0, S1, S2, S3) ^ P[i + 1];
}
xr ^= P[ROUNDS + 1];
table[s] = xr;
table[s + 1] = xl;
xr = xl; // end of cycle swap
xl = table[s];
}
}

private static void setKey(byte[] key, int[] S0, int[] S1, int[] S2, int[] S3, int[] P)
{
/*
* - comments are from _Applied Crypto_, Schneier, p338 please be
* careful comparing the two, AC numbers the arrays from 1, the
* enclosed code from 0.
*
* (1) Initialise the S-boxes and the P-array, with a fixed string This
* string contains the hexadecimal digits of pi (3.141...)
*/
System.arraycopy(KS0, 0, S0, 0, SBOX_SK);
System.arraycopy(KS1, 0, S1, 0, SBOX_SK);
System.arraycopy(KS2, 0, S2, 0, SBOX_SK);
System.arraycopy(KS3, 0, S3, 0, SBOX_SK);
System.arraycopy(KP, 0, P, 0, P_SZ);
/*
* (2) Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with
* the second 32-bits of the key, and so on for all bits of the key (up
* to P[17]). Repeatedly cycle through the key bits until the entire
* P-array has been XOR-ed with the key bits
*/
int keyLength = key.length;
int keyIndex = 0;
for (int i = 0; i < P_SZ; i++)
{
// get the 32 bits of the key, in 4 * 8 bit chunks
int data = 0x0000000;
for (int j = 0; j < 4; j++)
{
// create a 32 bit block
data = (data << 8) | (key[keyIndex++] & 0xff);
// wrap when we get to the end of the key
if (keyIndex >= keyLength)
keyIndex = 0;
}
// XOR the newly created 32 bit chunk onto the P-array
P[i] ^= data;
}
/*
* (3) Encrypt the all-zero string with the Blowfish algorithm, using
* the subkeys described in (1) and (2)
*
* (4) Replace P1 and P2 with the output of step (3)
*
* (5) Encrypt the output of step(3) using the Blowfish algorithm, with
* the modified subkeys.
*
* (6) Replace P3 and P4 with the output of step (5)
*
* (7) Continue the process, replacing all elements of the P-array and
* then all four S-boxes in order, with the output of the continuously
* changing Blowfish algorithm
*/
processTable(0, 0, P, S0, S1, S2, S3, P);
processTable(P[P_SZ - 2], P[P_SZ - 1], S0, S0, S1, S2, S3, P);
processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1, S0, S1, S2, S3, P);
processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2, S0, S1, S2, S3, P);
processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3, S0, S1, S2, S3, P);
}

/**
* Encrypt the given input starting at the given offset and place the
* result in the provided buffer starting at the given offset. The input
* will be an exact multiple of our blocksize.
*/
private static void encryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex, byte[] key)
{
int[] S0, S1, S2, S3, P;
S0 = new int[SBOX_SK];
S1 = new int[SBOX_SK];
S2 = new int[SBOX_SK];
S3 = new int[SBOX_SK];
P = new int[P_SZ];
setKey(key, S0, S1, S2, S3, P);
int xl = BytesTo32bits(src, srcIndex);
int xr = BytesTo32bits(src, srcIndex + 4);
xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2)
{
xr ^= F(xl, S0, S1, S2, S3) ^ P[i];
xl ^= F(xr, S0, S1, S2, S3) ^ P[i + 1];
}
xr ^= P[ROUNDS + 1];
Bits32ToBytes(xr, dst, dstIndex);
Bits32ToBytes(xl, dst, dstIndex + 4);
}

/**
* Decrypt the given input starting at the given offset and place the
* result in the provided buffer starting at the given offset. The input
* will be an exact multiple of our blocksize.
*/
private static void decryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex, byte[] key)
{
int[] S0, S1, S2, S3, P;
S0 = new int[SBOX_SK];
S1 = new int[SBOX_SK];
S2 = new int[SBOX_SK];
S3 = new int[SBOX_SK];
P = new int[P_SZ];
setKey(key, S0, S1, S2, S3, P);
int xl = BytesTo32bits(src, srcIndex);
int xr = BytesTo32bits(src, srcIndex + 4);
xl ^= P[ROUNDS + 1];
for (int i = ROUNDS; i > 0; i -= 2)
{
xr ^= F(xl, S0, S1, S2, S3) ^ P[i];
xl ^= F(xr, S0, S1, S2, S3) ^ P[i - 1];
}
xr ^= P[0];
Bits32ToBytes(xr, dst, dstIndex);
Bits32ToBytes(xl, dst, dstIndex + 4);
}

private static int BytesTo32bits(byte[] b, int i)
{
return ((b[i + 3] & 0xff) << 24) | ((b[i + 2] & 0xff) << 16) | ((b[i + 1] & 0xff) << 8) | ((b[i] & 0xff));
}

private static void Bits32ToBytes(int in, byte[] b, int offset)
{
b[offset] = (byte) in;
b[offset + 1] = (byte) (in >> 8);
b[offset + 2] = (byte) (in >> 16);
b[offset + 3] = (byte) (in >> 24);
}

Код
// Точка входа.
try
{
    BlowfishEngine.processBlock(in, inOff, out, outOff, true, key);
}
catch (IOException e){}

Объект 1,использование многократное - для всех клиентов :)

0
N
nuit

User

Участник

Posts: 79

На форуме с: 05/02/2008

Репутация: +19

Рейтинг: 0

· 05/08/2009, 04:20 AM

смотри как у меня на Си всё просто и понятно :)

Код
/* blowfish.h */
typedef struct {
  u32 p[18];
  u32 s[1024];
} BlowfishContext;

void blowfish_encrypt(BlowfishContext *this, u8 *dst, const u8 *src);
void blowfish_decrypt(BlowfishContext *this, u8 *dst, const u8 *src);
int blowfish_setkey(BlowfishContext *this, const u8 *key, u32 keylen);

0
Игорь
Игорь

User

Новичок

Posts: 10

На форуме с: 05/05/2007

Репутация: +8

Рейтинг: 0

· 05/08/2009, 11:20 AM

Даже толком не зная С всё равно выглядит понятней )) Но здесь ява и особо ничего не поделаешь =\ Кстати спасибо за пояснение по поводу асинхронного IO на форуме AE,меня натолкнуло на верный путь ;)

0
Войдите или зарегистрируйтесь чтобы ответить