Почему шифрование Java и Delphi AES дает разные результаты? - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь зашифровать некоторые данные. У меня есть рабочий код Java, и мне нужно перенести его на Delphi.

Вот мой код Java:

public static String ByteArrayToHexString(byte[] bytes) {
    final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    char[] hexChars = new char[bytes.length * 2]; // Each byte has two hex characters (nibbles)
    int v;
    for (int j = 0; j < bytes.length; j++) {
        v = bytes[j] & 0xFF; // Cast bytes[j] to int, treating as unsigned value
        hexChars[j * 2] = hexArray[v >>> 4]; // Select hex character from upper nibble
        hexChars[j * 2 + 1] = hexArray[v & 0x0F]; // Select hex character from lower nibble
    }
    return new String(hexChars);
}

public static byte[] HexStringToByteArray(String s) throws IllegalArgumentException {
    int len = s.length();
    if (len % 2 == 1) {
        throw new IllegalArgumentException("Hex string must have even number of characters");
    }
    byte[] data = new byte[len / 2]; // Allocate 1 byte per 2 hex characters
    for (int i = 0; i < len; i += 2) {
        // Convert each character into a integer (base-16), then bit-shift into place
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                + Character.digit(s.charAt(i + 1), 16));
    }
    return data;
}

public static byte[] Encrypt(String apak, byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
    byte[] apk = HexStringToByteArray(apak);
    String DataStr = ByteArrayToHexString(data);
    String reconstitutedString = new String(data);

    Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
    SecretKeySpec key = new SecretKeySpec(apk, "AES");
    cipher.init(Cipher.ENCRYPT_MODE, key);

    //byte[] IV = cipher.getIV();  // NULL
    //String IVHex = ByteArrayToHexString(IV);

    return cipher.doFinal(data);
}

private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    byte[] data = HexStringToByteArray("8450696E670454696D650013323031382D31322D30352031353A34363A343700");

    try {
      byte[] encrypted = Encrypt("7823C4E346336621CB73868429D8CC93", data);
    } catch (Exception ex) {
        String err = ex.getMessage();
    }
}  

В Delphi я использую LockBox, но получаю разные результаты.

Вот мой код Delphi:

function HexToByteArr(const Hexstr: String): TArray<byte>;
var
  I: Integer;
begin
  SetLength(Result, Length(Hexstr) div 2);
  for I := 0 to (Length(Hexstr) div 2 - 1) do
    Result[I] := StrToInt('$' + Copy(Hexstr, (I * 2) + 1, 2));
end;

function EncryptText2(const AText, APassword: AnsiString): AnsiString;
var
  Codec: TCodec;
  CipherText: AnsiString;
begin
  Codec := TCodec.Create(nil);
  try
    Codec.CryptoLibrary := TCryptographicLibrary.Create(Codec);
    //
    Codec.StreamCipherId := Base64_ProgId;
    Codec.BlockCipherId := Format(AES_ProgId, [128]);
    Codec.ChainModeId := ECB_ProgId;
    //
    Codec.password := APassword;
    Codec.EncryptAnsiString(AText, CipherText);
    //
    Result := CipherText;
  finally
    Codec.Free;
  end;
end;

procedure SimpleEncrypt;
var
  _DataHex: string;
  _DataBytes: TArray<Byte>;
  _DataStr: AnsiString;

  _EncryptedStr: AnsiString;
  _EncryptedBytes: TArray<Byte>;
begin
  _DataHex := '8450696E670454696D650013323031382D31322D30352031353A34363A343700';
  _DataBytes := HexToByteArr(_DataHex);
  _DataStr := TEncoding.ANSI.GetString(_DataBytes);

  _EncryptedStr := EncryptText2(_DataStr, '7823C4E346336621CB73868429D8CC93');
  _EncryptedBytes := TEncoding.ANSI.GetBytes(_EncryptedStr);
end;

Java-код производит

DFCC3CB95BEA276E6833207316B008DA6D219AA36A81AD6E75800BC898AE43B8

пока код Delphi выдает

68464270626D634556476C745A5141544D6A41784F4330784D6930774E5341784E546F304E6A6F304E77413D

Что я делаю не так?

...