Hello!

Java code

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 code

 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; 

the functions described are working, the verification code is also given

if I encode data in Java and try to decrypt it in Delphi, then I get abracadabra, tell me what could be the error?

I specify the same parameters for cryptography (it seems to me) in Java and Delphi, data between Java and Delphi is exchanged via sockets, the exchange code is not shown in it, I’m sure I checked the transfer of non-coded text is correct.

PS I look at the code ... and why I did not think about Java before, 5 times the code is shorter and does the same.

Closed due to the fact that the issue is too general for participants aleksandr barakin , user194374, VenZell , StateItPrimitive , Grundy 12 Mar '16 at 18:43 .

Please correct the question so that it describes the specific problem with sufficient detail to determine the appropriate answer. Do not ask a few questions at once. See “How to ask a good question?” For clarification. If the question can be reformulated according to the rules set out in the certificate , edit it .

  • I apologize for formatting the code, I'm here for the first time. Tell me how to fix it, I will reformat it (if necessary). - Vasya Ivanov
  • 2
    Never work with strings when encrypting. Because the string for the cryptographer is a set of bytes, the contents of which depend on the encoding. In Java, emnip, UTF8 is used by default. In Delphi before 2009 - AnsiString, after - UnicodeSting. Naturally, the byte content is different, so the output is nonsense. - kami
  • "Code is shorter" - and you try not to use Java wrappers for encryption functions, look where it is simpler :) In Delphi, there are enough classes-sets of crypto users. Use them if the native implementation is not comfortable. - kami
  • one
    And by the way - in Java code, you explicitly take a set of bytes instead of a string. Why do you think that in Delphi it is not necessary to do this and work directly with the content? Please indicate Delphi version . - kami

0