Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Помогите пожалуйста перевести код из Delphi в Java / 15 сообщений из 15, страница 1 из 1
07.03.2016, 14:57
    #39187178
Mandarin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Всем привет!

Java код

Код: 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.
public class MyCrypt {

    public static byte[] encrypt(String key, String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        Cipher cp = Cipher.getInstance("RC4");
        SecretKeySpec ks = new SecretKeySpec(md.digest(key.getBytes("ASCII")), "RC4");
        cp.init(Cipher.ENCRYPT_MODE, ks);
        return cp.doFinal(data.getBytes("ASCII"));
    }

    public static String decrypt(String key, byte[] data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        Cipher cp = Cipher.getInstance("RC4");
        SecretKeySpec ks = new SecretKeySpec(md.digest(key.getBytes("ASCII")), "RC4");
        cp.init(Cipher.DECRYPT_MODE, ks);
        return new String(cp.doFinal(data), "ASCII");
    }
}

// проверка функции
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String pass = "password";
        String str = "privet";
        try {
            byte[] b = MyCrypt.encrypt(pass, str);
            System.out.println(MyCrypt.decrypt(pass, b));
        } catch (Exception ex) {
            Logger.getLogger(Form1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }  



код Delphi
Код: pascal
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.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
function CryptAcquireContext(phProv        :PCardinal;
                              pszContainer :PAnsiChar;
                              pszProvider  :PAnsiChar;
                              dwProvType   :DWORD;
                              dwFlags      :DWORD) :BOOL; stdcall;

function CryptCreateHash(hProv   :Cardinal;
                         Algid   :Cardinal;
                         hKey    :Cardinal;
                         dwFlags :DWORD;
                         phHash  :PCardinal) :BOOL; stdcall;

function CryptDeriveKey(hProv     :Cardinal;
                        Algid     :Cardinal;
                        hBaseData :Cardinal;
                        dwFlags   :DWORD;
                        phKey     :PCardinal) :BOOL; stdcall;

function CryptEncrypt(hKey       :Cardinal;
                      hHash      :Cardinal;
                      Final      :BOOL;
                      dwFlags    :DWORD;
                      pbData     :PBYTE;
                      pdwDataLen :PDWORD;
                      dwBufLen   :DWORD) :BOOL; stdcall;

function CryptDecrypt(hKey       :Cardinal;
                      hHash      :Cardinal;
                      Final      :BOOL;
                      dwFlags    :DWORD;
                      pbData     :PBYTE;
                      pdwDataLen :PDWORD) :BOOL; stdcall;

function CryptDestroyHash(hHash: Cardinal) :BOOL; stdcall;
function CryptDestroyKey(hKey: Cardinal) :BOOL; stdcall;

function CryptReleaseContext(hProv   :Cardinal;
                             dwFlags :DWORD) :BOOL; stdcall;

function CryptHashData(hHash       :Cardinal;
                 const pbData      :PBYTE;
                       dwDataLen   :DWORD;
                       dwFlags     :DWORD) :BOOL; stdcall;

function CryptAcquireContext; external ADVAPI32 name 'CryptAcquireContextA';
function CryptCreateHash; external ADVAPI32 name 'CryptCreateHash';
function CryptDeriveKey; external ADVAPI32 name 'CryptDeriveKey';
function CryptEncrypt; external ADVAPI32 name 'CryptEncrypt';
function CryptDecrypt; external ADVAPI32 name 'CryptDecrypt';
function CryptHashData; external ADVAPI32 name 'CryptHashData';
function CryptDestroyHash; external ADVAPI32 name 'CryptDestroyHash';
function CryptDestroyKey; external ADVAPI32 name 'CryptDestroyKey';
function CryptReleaseContext; external ADVAPI32 name 'CryptReleaseContext';

function encrypt(hProv: Cardinal; ASourceStr: String; APassword: String): String;
 var
 data: String;
 hKey: Cardinal;
 lBufLen: DWORD;
 DataSize: Integer;
 hHash: Cardinal;
 lisEnd: Boolean;
 Poz: Integer;
 const
 // взято тут https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa375549(v=vs.85).aspx
 CALG_SHA = $00008004;
 CALG_RC4 = $00006801;
 //
 CU_BuffSize = 512;
begin
 Result := '';
 {создаем хеш-объект}
 if not CryptCreateHash(hProv, CALG_SHA, 0, 0, @hHash) then
  RaiseLastOSError;
 try
  DataSize := Length(ASourceStr);
  {хешируем пароль}
  if not CryptHashData(hHash, @APassword[1], length(APassword), 0) then
   RaiseLastOSError;
  {создаем ключ на основании пароля для потокового шифра RC4}
  if not CryptDeriveKey(hProv, CALG_RC4, hHash, 0, @hKey) then
   RaiseLastOSError;
  {шифруем данные}
  Poz := 0;
  repeat
   lBufLen := DataSize - Poz;
   if lBufLen > 0 then
    begin
     if lBufLen > CU_BuffSize then
      lBufLen := CU_BuffSize;
     data := Copy(ASourceStr,Poz+1,lBufLen);
     Inc(Poz, lBufLen);
    end;
   lisEnd := Poz >= DataSize;
   if not CryptEncrypt(hKey, 0, lisEnd, 0, @data[1], @lBufLen, CU_BuffSize) then
    RaiseLastOSError;
   Result := Result + data;
  until lisEnd;
 finally
  {уничтожаем хеш-объект}
  CryptDestroyHash(hHash);
  CryptDestroyKey(hKey);
 end;
end;

function decrypt(hProv: Cardinal; ASourceStr: String; APassword: String): String;
 var
 data: String;
 hKey: Cardinal;
 lBufLen: DWORD;
 hHash: Cardinal;
 Poz: Integer;
 lisEnd: Boolean;
 DataSize: Integer;
 const
 // взято тут https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa375549(v=vs.85).aspx
 CALG_SHA = $00008004;
 CALG_RC4 = $00006801;
 //
 CU_BuffSize = 512;
begin
 Result := '';
 if not CryptCreateHash(hProv, CALG_SHA, 0, 0, @hHash) then
  RaiseLastOSError;
 try
  DataSize := Length(ASourceStr);
  {хешируем пароль}
  if not CryptHashData(hHash, @APassword[1], length(APassword), 0) then
   RaiseLastOSError;
  {создаем ключ на основании пароля для потокового шифра RC4}
  if not CryptDeriveKey(hProv, CALG_RC4, hHash, 0, @hKey) then
   RaiseLastOSError;
  {дешифруем данные}
  Poz := 0;
  repeat
   lBufLen := DataSize - Poz;
   if lBufLen > 0 then
    begin
     if lBufLen > CU_BuffSize then
      lBufLen := CU_BuffSize;
     data := Copy(ASourceStr,Poz+1,lBufLen);
     Inc(Poz, lBufLen);
    end;
   lisEnd := Poz >= DataSize;
   if not CryptDecrypt(hKey, 0, lisEnd, 0, @data[1], @lBufLen) then
    RaiseLastOSError;
   Result := Result + data;
  until lisEnd;
 finally
  {уничтожаем хеш-объект}
  CryptDestroyHash(hHash);
  CryptDestroyKey(hKey);
 end;
end;

// проверка функции
procedure TForm1.Button1Click(Sender: TObject);
 var
 pass: string;
 data: string;
 enc: string;
 prov: cardinal;
 const
 CU_ProvType = 1;
 CU_CRYPT_VERIFYCONTEXT = $F0000000;
begin
 pass := 'password';
 data := 'privet';
 CryptAcquireContext(@prov, nil, nil, CU_ProvType, CU_CRYPT_VERIFYCONTEXT);
 enc := encrypt(prov,data,pass);
 showmessage(decrypt(prov,enc,pass));
end;



описанные функции работаю, код проверки тоже приведен

если я кодирую данные в Java а расшифровать пытаюсь в Delphi то получаю абракадабру, подскажите в чем может быть ошибка?

параметры для криптографии я указываю одинаковые (как мне кажется) в Java и Delphi,
данным между Java и Delphi обмениваюсь через сокеты, код обмена не привожу в нем я уверен, проверял передачу не кодированного текста обмен происходит правильно.

P.S. смотрю на код... и почему я раньше про Java не думал, в 5 раза код короче а делает тоже самое.
...
Рейтинг: 0 / 0
07.03.2016, 15:33
    #39187194
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Код особо не читал.
Первая мысль: что там насчет строк?
В джаве вижу явный getBytes("ACSII"). В дельфи вижу передачу указателя на строку. Строки там с D2009 UTF-16.
...
Рейтинг: 0 / 0
07.03.2016, 15:39
    #39187200
Mandarin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Alexander A. Sak,

у меня версия Delphi BDS 2006, там кодировка Windows-1251, поэтому на стороне Java указываю явно "ASCII"(то же самое что Windows-1251)

вот пример кода когда Java отправляет данные Delphi получает и возвращает обратно

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Socket cs = new Socket(addr, 3456);
            OutputStream out = cs.getOutputStream();
            InputStream in = cs.getInputStream();
            String s = "privet";
            String k = "password";
            out.write(MyCrypt.encrypt(k, s));
            out.write('\r');
            byte[] b = new byte[5];
            in.read(b);
            System.out.println(MyCrypt.decrypt(k, b));
            cs.close();



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
procedure TMyClass.ReadData;
 var
 i: integer;
 buf: array of byte;
 b: byte;
 s: String;
 r: integer;
begin
 i := 0;
 while True do
  begin
   ClientSocket.ReadBuf(b,1);
   if (b = 13) then
    break;
   SetLength(buf,i+1);
   buf[i] := b;
   inc(i);
  end;
// SetLength(s,i);
// SetString(s, PChar(@buf[0]), i);
// s := UnCryptStr(hCryptProv,s,'wml7rds');
// r := StrToIntDef(s,0);
 ClientSocket.SendBuf(PChar(@buf[0])^,i);
end;
...
Рейтинг: 0 / 0
07.03.2016, 15:59
    #39187207
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Mandarin,
если D - D и J - J сами в себе работают, значит криптопровайдеры или параметры у него разные.
Код больше, т.к. в D ты писал процедурно, без классов и привёл заголовочные файлы.
- закодируй строку в файл Мама мыла раму и сравнивай побайтово. Там ведь время не зашивается? Байтовый поток повторяемый?
...
Рейтинг: 0 / 0
07.03.2016, 16:05
    #39187210
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Тогда надо делать crypt/decrypt и сравнивать каждый шаг в джаве и дельфи, чтобы найти где расхождение.

Исходный масссив байтов тут и там -- одинаковый?
Аналогично:
- Результирующий массив байтов после SHA1()
- Результирующий массив байтов после RC4()
...
Рейтинг: 0 / 0
07.03.2016, 16:06
    #39187212
Mandarin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Petro123,

то что параметры алгоритмов разные это вероятнее всего, но пока не могу понять какие.

в Java тип byte от -128 до 127 в Delphi от 0 до 255 поэтому напрямую сравнивать не получится.

для сравнения с делал две проверки
1. посылал по сокету Java не шифрованный текст в виде байт, принимал в виде байт переводил в строку - получал верный результат
2. посылал по сокету Java шифрованный текст в виде байт, принимал в виде бай отправлял обратно в виде бай, расшифровывал - получал верный результат
из этого делаю вывод что конвертация из Java.byte в Delphi.byte делается верно, ни потерь ни искажения нет
остается (на мой взгляд) только одно - подбирать параметры для функций криптографии.
...
Рейтинг: 0 / 0
07.03.2016, 16:07
    #39187213
Mandarin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Alexander A. SakТогда надо делать crypt/decrypt и сравнивать каждый шаг в джаве и дельфи, чтобы найти где расхождение.

Исходный масссив байтов тут и там -- одинаковый?
Аналогично:
- Результирующий массив байтов после SHA1()
- Результирующий массив байтов после RC4()

сейчас проверю
...
Рейтинг: 0 / 0
07.03.2016, 16:22
    #39187226
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Mandarinу меня версия Delphi BDS 2006, там кодировка Windows-1251, поэтому на стороне Java указываю явно "ASCII"(то же самое что Windows-1251)В пределах первой половины 256-байтовой таблицы? Ну, дык, при наличии отсутствия EBCDIC - кто бы сомневался ...
Вот что вы собрались со второй половиной делать?..

P.S. Привыкайте тестировать на реальных данных.
Если "windows-1251", то "Это я", а не "privet".
...
Рейтинг: 0 / 0
07.03.2016, 17:12
    #39187252
Mandarin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Basil A. Sidorov,

"В пределах первой половины 256-байтовой таблицы? Ну, дык, при наличии отсутствия EBCDIC - кто бы сомневался ...
Вот что вы собрались со второй половиной делать?.."

что вы имели ввиду? я вас не понял.
...
Рейтинг: 0 / 0
07.03.2016, 17:34
    #39187257
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Mandarin,
выбрасывай в файл поток. Так проще будет.
...
Рейтинг: 0 / 0
07.03.2016, 17:50
    #39187262
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Mandarinпоэтому на стороне Java указываю явно "ASCII"(то же самое что Windows-1251)
кто сказал, что одно и то же? в Java имеется windows-1251
...
Рейтинг: 0 / 0
07.03.2016, 17:57
    #39187267
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
ИзопропилMandarinпоэтому на стороне Java указываю явно "ASCII"(то же самое что Windows-1251)
кто сказал, что одно и то же? в Java имеется windows-1251

Ну ошибается человек.
Для теста на строке "privet" байты же будут одинаковыми в ASCII и 1251. Пусть хоть так пока правильный результат получит. Потом расскажем, что все не так просто.
...
Рейтинг: 0 / 0
07.03.2016, 18:35
    #39187275
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Mandarinчто вы имели ввиду? я вас не понял.Обработку национальных символов надо проверять (сюрприз!) на национальных символах.
Вот когда ваш тест корректно обработает "Привет, мир", тогда и можете утверждать, что "ascii" и "windows-1251" - синонимы.
...
Рейтинг: 0 / 0
07.03.2016, 20:20
    #39187307
Mandarin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Basil A. Sidorov,

возможно с кодировками я напутал, но для цифр и английского текста это не должно быть причиной того что декодирование не проходит.
...
Рейтинг: 0 / 0
07.03.2016, 21:26
    #39187317
Mandarin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите пожалуйста перевести код из Delphi в Java
Mandarin,

похоже я понял в чем дело,

я сравнил по байтно (Alexander A. Sak спасибо за совет) хеши ключей, хеши совпадают, потом сравнил длины получившихся ключей
в Delphi функции мне говорят что у меня длина ключа 128 бит а в Java длина ключа 20 байт или 160 бит, как в Java задать размер ключа?
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Помогите пожалуйста перевести код из Delphi в Java / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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