Отправка byte[] через UDP приводит к изменению значения byte[]

Я пытаюсь установить связь с сервером и клиентом с использованием UDP, и это включает отправку зашифрованного текста с использованием RC4 друг другу. Это выглядит примерно так:

  1. Запустить хост.

  2. Запустить клиент.

  3. Клиент отправляет зашифрованный текст, используя RC4

  4. Хост получает зашифрованный текст и расшифровывает его с помощью RC4

Мой RC4 взят из онлайн-источника и, кажется, работает. Если бы я выполнял как шифрование, так и дешифрование на стороне клиента (в целях тестирования), это сработало бы. Но проблема возникает после того, как я отправил свой зашифрованный текст на хост. Когда мой хост расшифровывает сообщение, результат не является ожидаемым.

Вот пример моего кода на клиенте:

RC4 rc4 = new RC4(rc4Key);      
String message = "Hello";       
char[] result = rc4.encrypt(message.toCharArray());
System.out.println("encrypted string: " + new String(result));              //M®FW?
System.out.println("decrypted string: " + new String(rc4.decrypt(result))); //Hello

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

sentence = new String(result);
sendData = sentence.getBytes();
sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);        
clientSocket.send(sendPacket);

И на моей принимающей стороне я буду получать зашифрованный текст

receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
realSentence = Arrays.copyOf(receivePacket.getData(), receivePacket.getLength());
sentence = new String(realSentence);
RC4 rc4 = new RC4(ad.toString());               
char[] result = rc4.decrypt(sentence);
System.out.println("decrypted string: " + new String(result)); //H?ll?

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


person user1958567    schedule 28.01.2014    source источник
comment
Почему вы используете случайную реализацию RC4, а не встроенную в JCE?   -  person ntoskrnl    schedule 28.01.2014


Ответы (1)


Для справки в будущем, хороший способ отладки — забыть о криптографии и написать тест, который отправляет известный массив байтов (содержащий специальный символ) с одной стороны на другую.

При этом я думаю, что эта строка виновата:

sendData = sentence.getBytes();

Здесь вы не указываете набор символов при получении байтов. Это означает, что вы используете платформу по умолчанию. На другом конце вашего соединения вы делаете это:

sentence = new String(realSentence);

Опять же, преобразование байтов в строку без указания набора символов. Я предполагаю, что ваш пункт назначения имеет другой набор символов по умолчанию.

Примечание: этот код вообще кажется странным. Почему шифр RC4 должен возвращать массив символов? Вместо этого я бы искал, например, код, который управляет массивами байтов и просто отправляет необработанные значения по сети.

person Duncan Jones    schedule 28.01.2014
comment
Привет, Дункан, спасибо за вклад. Мой результат находится в charArray, поэтому мне придется преобразовать их в байты перед отправкой. Не приведет ли это к потере данных? Редактировать: я тоже понятия не имею. Может быть, мне лучше найти другой пример RC4, в котором используется массив байтов? - person user1958567; 28.01.2014
comment
@ user1958567 Либо а) укажите набор символов, например UTF-8, на обоих концах, либо б) (предпочтительно) найдите реализацию RC4, которая работает с массивами байтов, а не с массивами символов. - person Duncan Jones; 28.01.2014