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

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
Помогите пожалуйста перевести код из Delphi в Java
    #39187194
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код особо не читал.
Первая мысль: что там насчет строк?
В джаве вижу явный getBytes("ACSII"). В дельфи вижу передачу указателя на строку. Строки там с D2009 UTF-16.
...
Рейтинг: 0 / 0
Помогите пожалуйста перевести код из Delphi в Java
    #39187200
Фотография Mandarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Помогите пожалуйста перевести код из Delphi в Java
    #39187207
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mandarin,
если D - D и J - J сами в себе работают, значит криптопровайдеры или параметры у него разные.
Код больше, т.к. в D ты писал процедурно, без классов и привёл заголовочные файлы.
- закодируй строку в файл Мама мыла раму и сравнивай побайтово. Там ведь время не зашивается? Байтовый поток повторяемый?
...
Рейтинг: 0 / 0
Помогите пожалуйста перевести код из Delphi в Java
    #39187210
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда надо делать crypt/decrypt и сравнивать каждый шаг в джаве и дельфи, чтобы найти где расхождение.

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

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

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

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

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

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

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

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

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

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

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

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

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


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