powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / помогите пожалуйста разобраться с криптографией
25 сообщений из 27, страница 1 из 2
помогите пожалуйста разобраться с криптографией
    #39183655
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!

пытаюсь сделать кодирование/декодирование данных, пока что тоне очень выходит, подскажите что делаю не так?

описание класа
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class MyCrypt {

    private final Cipher FCipher;

    MyCrypt() throws NoSuchAlgorithmException, NoSuchPaddingException {
        FCipher = Cipher.getInstance("RC4");
    }

    public String Encrypt(String Key, String Data) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        SecretKeySpec FKey;
        FKey = new SecretKeySpec(Key.getBytes(), "RC4");
        FCipher.init(Cipher.ENCRYPT_MODE, FKey);
        return new String(FCipher.doFinal(Data.getBytes()));
    }

    public String Decrypt(String Key, String Data) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        SecretKeySpec FKey;
        FKey = new SecretKeySpec(Key.getBytes(), "RC4");
        FCipher.init(Cipher.DECRYPT_MODE, FKey);
        return new String(FCipher.doFinal(Data.getBytes()));
    }
}



вызов
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        MyCrypt mc = null;
        try {
            mc = new MyCrypt();
        } catch (NoSuchAlgorithmException | NoSuchPaddingException ex) {
            Logger.getLogger(Form1.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            String src = "привет мир";
            String key;
            key = "password12345";
            String tmp;
            tmp = mc.Encrypt(key,src);
            System.out.println("encrypted: "+tmp);
            tmp = mc.Decrypt(key, tmp);
            System.out.println("decrypted: "+tmp);
            
        } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
            Logger.getLogger(Form1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }



на выходе получаю кракозяблики
encrypted: ��ddk\:ʆ~�0� !D�
decrypted: �Y�=�x#�rcAkp�ط�P�7{�
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183691
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С вот этой либой на много проще
http://www.jasypt.org
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183700
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mandarin,

Проблема вашего кода в непонимании String и кодировок и их отношению к byte[]
Когда вы получили шифр в виде byte[], то ваш перевод его в String и обратно в byte[] теряет данные.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183710
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

согласен с непониманием :) спасибо за подсказку!
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183727
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попробовал сейчас сделать так

Код: java
1.
2.
3.
4.
5.
6.
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String s = "привет";
        String s2;
        s2 = new String(s.getBytes());
        System.out.println(s2);
    }



вывод "привет"

данные вроде как не потерялись, почему он теряются при тех же самых действиях при encrypt/decrypt ?
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183750
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mandarin,

Потому что с логикой надо тоже дружить. То что любую строку можно предоставить в виде набора байт в определенной кодировке, никак не обозначает того что любой набор байт можно представить в виде строки в любой кодировке. Вот этот символ � вам на данный факт прямо указывает.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183812
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

какую можно кодировку использовать чтобы не было потери данных?

p.s. если оперировать byte[] у меня получилось кодировать/декодировать
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183820
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mandarinкакую можно кодировку использовать чтобы не было потери данных?
Base64 одна из самых распространенных.
Надо только различать кодировки, для представления текста в виде байт ( https://en.wikipedia.org/wiki/Character_encoding), которые предназначены для хранения текстовых данных в двоичной памяти.
И кодировки для представления байт в виде текста ( https://en.wikipedia.org/wiki/Binary-to-text_encoding), которые предназначены для передачи двоичных данных по текстовым каналам.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183912
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

спасибо
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39183983
Partisan M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczBase64 одна из самых распространенных.

В данной задаче применение Base64 лишено смысла.

Mandarinесли оперировать byte[] у меня получилось кодировать/декодировать

Тогда чего вам ещё надо. Результат шифрования - набор байтов, а не строка. Но программа кишит ошибками. Основные ошибки - что названия переменных и функций начинаются с больших букв. Это выдаёт лоха, что вообще ни к чему, и мешает чтению исходного кода.
Названия переменных и функций принято писать с маленькой буквы, а классов с большой.

Затем, мелкая ошибка, из-за которой программа даёт неправильный результат - при преобразовании строки в набор байтов и обратно надо указывать набор символов строки.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184000
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Partisan MЗатем, мелкая ошибка, из-за которой программа даёт неправильный результат - при преобразовании строки в набор байтов и обратно надо указывать набор символов строки.
Ошибка программы не в этом. Так как все конвертации происходят внутри одной JVM, то явное указание Charset почти ни на что не влияет. Конвертации в разные Charset всё равно не будет. Проблема в попытке представить byte[], который изначально строкой не является в виде строки.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184008
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Partisan MBlazkowiczBase64 одна из самых распространенных.
В данной задаче применение Base64 лишено смысла.
Лишено смысла делать категоричные и ошибочные заявления, когда их читают другие. Мало ли чего подумают.
Автор хочет иметь шифр в виде строки. JCA оперирует только байтами. Что там у тебя лично лишено смысла, автору, полагаю, не интересно.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184041
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
расскажу для чего мне все это надо
у меня есть рабочий проект клиент серверное приложение и клиент и сервер написаны на Delphi.
сейчас я хочу сделать еще одно клиентское приложение на Jave, для того чтобы новый клиент подключался к старому серверу, нужно повторить протокол обмена в котором присутствует шифрование данных.
в существующем протоколе обмена криптография сделана с помощью Windows Crypto API, там я оперирую строками, т.е. на вход кодеру подается строка и на выходе получается строка (из кракозябликов) которая подается на вход декодеру

в итоге должно получится так
Java->String="привет мир"->encode->Delphi->decode->"привет мир"
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184052
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mandarin,

Для того чтобы повторить протокол, надо понимать как он работает. Потому что Delphi очень любит конвертировать в строку "как попало". И оно работает. Но без понимание "как же именно оно попало", повторить тоже самое на Java будет сложно.
Ну, и ещё такое бывает, если наворачивать свои какие-то велосипеды, вместо стандартов типа SSL.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184060
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

как работает протокол я понимаю, я сам его писал, велосипед я тоже сделал специально

если Delphi и Java или еще кто-то третий используют одинаковый алгоритм шифрование то и результаты должны быть одинаковые.
вот мне как раз и нужно добиться одинакового результата.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184067
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mandarinесли Delphi и Java или еще кто-то третий используют одинаковый алгоритм шифрование то и результаты должны быть одинаковые. вот мне как раз и нужно добиться одинакового результата.
Правильно. Но, как я вам уже объяснил выше, помимо самого шифрования, есть ещё и огромная разница в представлении данных в виде строки. Алгоритм шифрования на это никак не влияет. Это уже деталь инфраструктуры надстроенной над ним.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184071
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Результат будет одинаковый, если шифруется одинаковый поток байт .
Если "подаётся на вход строка" - может быть куч(к)а вариантов.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184076
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

поправьте меня если я ошибаюсь...

Chipher.doFinal() - отдаст мне набор байт (байты они ведь одинаковые для всех для Java и Delphi например)

этот набор байт я передам в Delphi для преобразования в String и по идее должно получиться то что ждет мой decoder в Delphi?
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184086
Partisan M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczЛишено смысла делать категоричные и ошибочные заявления, когда их читают другие. Мало ли чего подумают.
Автор хочет иметь шифр в виде строки. JCA оперирует только байтами. Что там у тебя лично лишено смысла, автору, полагаю, не интересно.

Весь этот текст лишён смысла.
Как сделать правильно - я кратко объяснил, но вечером могу представить исправленный пример.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184117
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Partisan MВесь этот текст лишён смысла.
Как и твоя аргументация. А так её вообще же нет.

Partisan MКак сделать правильно - я кратко объяснил, но вечером могу представить исправленный пример.
Не утруждай себя.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184323
Partisan M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz
Я слишком устал, чтобы пререкаться с троллем, поэтому не буду утруждать себя.

Но на вопрос автора темы отвечу, раз обещал.

В чём ошибка.
Шифрование работает не с символами, а с байтами. Поэтому строку надо преобразовать в набор байтов перед кодированием и набор байтов после декодирования надо преобразовать в строку. Но одной и той же строке могут соответствовать разные наборы байтов в зависимости от её набора символов. Нельзя полагаться на набор символов по умолчанию, надо указывать в явном виде.
Способы:
Код: java
1.
2.
3.
4.
String s = "привет мир";
byte [] bytes = s.getBytes("UTF-8");
...
String decodedString = new String (bytes, "UTF-8");


Здесь UTF-8 - обычно предпочтительная для работы кодировка. Надо узнать, какая используется. Но если понадобится Windows-1251, то можно записать как "Cp1251". Вот исправленный пример. Только вызов теста производится из функции main, поскольку я поленился воспроизводить интерфейс пользователя:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class MyCript {
	
	private Cipher FCipher = Cipher.getInstance("RC4");

    MyCript() throws NoSuchAlgorithmException, NoSuchPaddingException {
        FCipher = Cipher.getInstance("RC4");
    }

    public byte[]  Encrypt(String Key, String Data) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        SecretKeySpec FKey;
        FKey = new SecretKeySpec(Key.getBytes("UTF-8"), "RC4");
        FCipher.init(Cipher.ENCRYPT_MODE, FKey);
        return FCipher.doFinal(Data.getBytes("UTF-8"));
    }

    public byte[] Decrypt(String Key, byte [] Data) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        SecretKeySpec FKey;
        FKey = new SecretKeySpec(Key.getBytes("UTF-8"), "RC4");
        FCipher.init(Cipher.DECRYPT_MODE, FKey);
        return FCipher.doFinal(Data);
    }

	public static void main(String[] args) {
		try {
			MyCript test = new MyCript();
			test.doTest();
		} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void doTest() {
		try {
            String src = "привет мир";
            String key;
            key = "password12345";
            byte [] tmp;
            tmp = Encrypt(key,src);
            System.out.println("encrypted: "+ new String (tmp, "UTF-8"));
            tmp = Decrypt(key, tmp);
            System.out.println("decrypted: "+ new String (tmp, "UTF-8"));
            
        } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException ex) {
            ex.printStackTrace();
        }		
	}

}



Примечание. Совет использовать Base64 был совершенно бессмысленным. Шифрованию это не помогает, поскольку Base64 кодирует байты и результат также зависит от кодировки текста. Зрительному контролю при отладке тоже не помогает, поскольку при кодировку Base64 в одном символе могут быть перемешаны биты из разных байтов. Для контроля можно преобразовать массив байтов в строку их числовых значений. Вот, наспех набросал: функция asString и вызывающая программа
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
import java.io.UnsupportedEncodingException;

public class Test0 {

	public static void main(String[] args) {
		String s = "абвгдеё";
		try {
			String hexString = asString(s.getBytes("UTF-8"));
			System.out.println (hexString);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

	}

	static String asString (byte [] bytes) {
		StringBuffer result = new StringBuffer("");
		for (byte b : bytes) {
			String hex = String.format("%1$1X", b);
			result.append(hex).append(" ");
			
		}
		return result.toString();
	}
}



Ещё примечание. Совет использовать библиотеку Jasypt или как её там, неудачный. Я посмотрел - документация скудная. Лучше Bouncy Castle. По ней хорошая документация, и есть поддержка российских алгоритмов. В этой, как её там, есть возможность вызова Bounce Castle, но из-за скудной документации я не понял, зачем она вообще нужна, если есть Bounce Castle. Ну фиг с ней.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184389
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mandarinв итоге должно получится так
Java->String="привет мир"->encode->Delphi->decode->"привет мир"

Тебе надо сделать так

Java->String="привет мир"->encode->byte[]->encodeBase64->String="encodedString"

А для декодирования

String="encodedString"->decodeBase64->byte[]->decode->String="привет мир"

Вообще... данная тема не имеет отношения к приптографии. Это скорее общие понятия о том
что можно делать с массивами байтов а что нет.

И делай так всегда.

Вообще всегда.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39184474
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Partisan MЯ слишком устал, чтобы пререкаться с троллем, поэтому не буду утруждать себя.
Спасибо.

Partisan MШифрование работает не с символами, а с байтами.
Не абстрактное "шифрование", а конкретно JCA API.

Partisan MПоэтому строку надо преобразовать в набор байтов перед кодированием и набор байтов после декодирования надо преобразовать в строку.
ТС это и делает же.

Partisan MНельзя полагаться на набор символов по умолчанию, надо указывать в явном виде.
Можно внутри одной JVM. Но так как автор собрался интегрироваться с Delphi сервером, то, да. Кодировку нужно указывать, чтобы обязательно совпала с противоположной стороной.

Partisan MСпособы:
Код: java
1.
2.
3.
4.
String s = "привет мир";
byte [] bytes = s.getBytes("UTF-8");
...
String decodedString = new String (bytes, "UTF-8");



А если использовать Charset.forName(), то не придется ловить дурацкий UnsupportedEncodingException.

Partisan MЗдесь UTF-8 - обычно предпочтительная для работы кодировка. Надо узнать, какая используется. Но если понадобится Windows-1251, то можно записать как "Cp1251".
Ну, и вообще
https://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html


Partisan MВот исправленный пример.
Убрал декодирование байтов в строку, как я изначально и указал? Похвально.

Partisan MПримечание. Совет использовать Base64 был совершенно бессмысленным.
Это твоё субъективное ничем не подкрепленное и даже ошибочное мнение. Весь мир обменивается шифрами и ключами на основе Base64, но тебе видится бессмысленным.

Partisan MШифрованию это не помогает
Спасибо, кэп. Я выше указал что кодирование нужно для передачи шифра по текстовым протоколам, которые более удобны пользователям.

Partisan Mпоскольку Base64 кодирует байты и результат также зависит от кодировки текста.
Сам хоть понял что сказал? То что пользовательские байты каким-то образом сформированы из текста к Base64 отношения не имеет.

Partisan MЗрительному контролю при отладке тоже не помогает

Ты шифр собрался зрительно контролировать? Умора.

Partisan MВот, наспех набросал: функция asString и вызывающая программа

Рукалицо.

Partisan MСовет использовать библиотеку Jasypt или как её там, неудачный.
По твоему скромному ошибочному и не аргументированному мнению? Тогда да.

Partisan MЯ посмотрел - документация скудная. Лучше Bouncy Castle. По ней хорошая документация, и есть поддержка российских алгоритмов. В этой, как её там, есть возможность вызова Bounce Castle, но из-за скудной документации я не понял, зачем она вообще нужна, если есть Bounce Castle. Ну фиг с ней.
Бедный, не разобрался? Ну, давай объясню.
Jasypt это такое упрощенное API, которое с одной стороны позволяет не заморачиваться с деталями реализации, а с другой стороны позволяет управлять этими деталями так как нужно разработчику. При этом, о чудо, оно поддерживает и JCA и Bouncy Castle. Тот который с "y" в слове Bouncy.

Вот тут есть пример
http://www.jasypt.org/easy-usage.html
Раздел Text encryption
Этот пример в 4 строчки заменяет весь тот говнокод, который вы тут развели.

Основная же фича Bouncy Castle это поддержка широчайшего диапазона кодирований и шифрований. Вот только автору оно нафиг не упало, если у него на Delphi один алгоритм, который и так в JCA реализован.
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39185346
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за помощь!

Вчера меня осенило... зачем мне повторять старые вещи когда то что мне нужно в Java есть по умолчанию.

то что мне надо это Java EE + EJB + Java SE (для рисования GUI)

поправьте меня если я ошибаюсь

1. я делаю некий *.jar который умеет соединятся с моим сервером приложений (Java EE)
2. и когда надо пользовательский GUI обновляется

т.е. все модули хранятся на моем сервере а клиент как бы ими пользуется, аналог web страницы только Descktop App
...
Рейтинг: 0 / 0
помогите пожалуйста разобраться с криптографией
    #39185365
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mandarin, если честно - берёт оторопь от той скорости с которой
ты отбросил предыдущее решение..

Вообще звучало со стороны как -
- Эврика! Ребята. Криптография вообще не нужна можно то-то и то-то.... e.t.c.

Ну дай бох.

P.S. А c кодирование в base64 всё равно разберись. Оно тебя настигнет еще раз.
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / помогите пожалуйста разобраться с криптографией
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]