Encrypted in Java and Decrypting in dart flutter Encrypted in Java and Decrypting in dart flutter dart dart

Encrypted in Java and Decrypting in dart flutter


In the Java code, the ciphertext is converted into a string using a charset encoding (like UTF-8). This generally corrupts the data. Here a binary-to-text encoding like base64 should be used.

The Java code posted in the question provides with the following changes:

import java.util.Base64;...Cipher desCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");...String plainText = "The quick brown fox jumps over the lazy dog";...System.out.println("encrypted: " + Base64.getEncoder().encodeToString(textencrypted));...

the following Base64 encoded ciphertext:

encrypted: Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVF

This ciphertext can be decrypted using the Pointy Castle package with the following Dart code:

import 'dart:convert';import 'dart:typed_data';import 'package:pointycastle/api.dart';import 'package:pointycastle/block/aes_fast.dart';import 'package:pointycastle/block/modes/ecb.dart';import 'package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart';import 'package:pointycastle/paddings/pkcs7.dart';...Digest sha1 = Digest("SHA-1");Uint8List key = sha1.process(utf8.encode('1234567890123456')).sublist(0, 16);Uint8List ciphertext = base64.decode('Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVF');ECBBlockCipher cipher = ECBBlockCipher(AESFastEngine());PaddedBlockCipher paddedCipher = new PaddedBlockCipherImpl(new PKCS7Padding(), cipher);PaddedBlockCipherParameters<CipherParameters, CipherParameters> paddingParams = new PaddedBlockCipherParameters(KeyParameter(key), null);paddedCipher.init(false, paddingParams);Uint8List plainText = paddedCipher.process(ciphertext);print(utf8.decode(plainText));

Please note the following: ECB is an insecure mode. More secure are CBC (see here for a dart example) or GCM, where the latter allows encryption as well as data authentication. Also the derivation of a key from a password with SHA-1 is insecure. Here a reliable key derivation function, e.g. PBKDF2, should be used.

Edit:
Converting a ciphertext into a string with a charset like UTF-8 will damage the data. You can find many posts on Stackoverflow, e.g. this one, which explains the problem in detail. This means that the Java code posted in your question won't work reliably if the ciphertext is converted with UTF-8.

However, there are charsets like ISO-8859-1 that do not corrupt the data. It is possible that such a charset is used on the server. This cannot be determined from the posted code, because no charset is specified during decoding (i.e. in new String(textencrypted)), so the default charset of the respective platform is applied, see here. Therefore, to check this possibility, you have to determine which default charset is used on the server.
Another way to analyze which encoding is used would be to check (or post) the code that is used to decrypt the ciphertext created by the server.

Most reliable is the use of encodings that are dedicated to convert binary data into a string, so called binary-to-text encodings, such as Base64, see here, which is why I used Base64 in the posted example.


You can verify the effects of a conversion using UTF-8 or ISO-8859-1 with the following Java code. The data from the posted example above is used as ciphertext:

convertDataWith(StandardCharsets.UTF_8);convertDataWith(StandardCharsets.ISO_8859_1);...private static void convertDataWith(Charset charset) {    String ciphertextBeforeB64 = "Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVF";    // Data from posted example    byte[] ciphertextBefore = Base64.getDecoder().decode(ciphertextBeforeB64);    String ciphertextCharset = new String(ciphertextBefore, charset);                                   // Convert to String with specified charset    byte[] ciphertextAfter = ciphertextCharset.getBytes(charset);                                       // Convert from String with specified charset    String ciphertextAfterB64 = Base64.getEncoder().encodeToString(ciphertextAfter);    System.out.println("Ciphertext BEFORE conversion: " + ciphertextBeforeB64);    System.out.println("Ciphertext AFTER conversion:  " + ciphertextAfterB64);  }

with the output:

Ciphertext BEFORE conversion: Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVFCiphertext AFTER conversion:  Mj4877+9EiUSJ1xUdUcjDyLvv73vv73vv71RCO+/vQd7aO+/vUI7ODbvv71e77+977+9FyPvv73vv73vv73Euy0m77+9B++/vVRlRQ==Ciphertext BEFORE conversion: Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVFCiphertext AFTER conversion:  Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVF

As explained above, UTF-8 corrupts the data.