I have a string that was encrypted in Laravel PHP.
The encryption function is as below.
public function getEncryptedString()
{
try {
$m2 = Crypt::encryptString('Thismessagewillbeencrypted', 'theencryptionkey');
return response()->json([
'm2' => $m2 ? $m2 : null,
], 200);
} catch (Exception $e) {
return response()->json([
'message' => 'Something went wrong',
'error' => $e->getMessage()
], 400);
}
}
the Flutter/dart is as below.
import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/export.dart';
Uint8List aesCbcDecrypt(Uint8List key, Uint8List iv, Uint8List cipherText) {
assert([128, 192, 256].contains(key.length * 8), 'Invalid key length.');
assert(128 == iv.length * 8, 'Invalid IV length. IV must be 128 bits');
assert(
128 == cipherText.length * 8,
'Invalid cipherText length. cipherText must be 128 bits.',
);
// Create a CBC block cipher with AES, and initialize with key and IV
final cbc = CBCBlockCipher(AESEngine())
..init(false, ParametersWithIV(KeyParameter(key), iv)); // false=decrypt
// Decrypt the cipherText block-by-block
final paddedPlainText = Uint8List(cipherText.length); // allocate space
var offset = 0;
while (offset < cipherText.length) {
offset += cbc.processBlock(cipherText, offset, paddedPlainText, offset);
}
assert(
offset == cipherText.length,
'Decryption process did not process the entire cipherText.',
);
return paddedPlainText;
}
void decrypter() {
const encryptedString =
'eyJpdiI6IjFLc001N25UNzhQNXVMOGxHMGZzeEE9PSIsInZhbHVlIjoiVmU0SGVVL0xFQUtCeW83NkVSSXpOZDRXWUV2allZTEg0c3J4aTJNV1BkST0iLCJtYWMiOiI2Yjk2MGQ3NzAzOTIwMjM5YTc5NTEwMjM2NWFlNDM1MTYwZDI5NzBjNjE4MWQzN2Q0OTE4NmZjNDUxZjNjZGUwIiwidGFnIjoiIn0=';
const key = 'theencryptionkey';
final json = jsonDecode(utf8.decode(base64Decode(encryptedString)));
final decodedKey = base64Decode(key);
final decodedIV = base64Decode(json['iv'] as String);
final decodedCipherText = base64Decode(json['value'] as String);
// Ensure cipherText has the correct length
final cipherText =
decodedCipherText.sublist(0, 16); // Take the first 16 bytes (128 bits)
final result = aesCbcDecrypt(decodedKey, decodedIV, cipherText);
print(base64.encode(result));
}
the encryptedString is the response String I am getting when Thismessagewillbeencrypted is encrypted with theencryptionkey key.
This was of course to test the process.
but While testing to decrypt the encrypted string in a flutter dart code, I keep getting different errors. I can’t understand what I am doing wrong.
Any guide on how to decrypt would help?
I am using pointycastle package, and following this.
2
Answers
I have no experience with the pointycastle package, however, I have worked with the encrypt package in the past.
If you don’t mind switching packages you could try the following:
flutter pub add encrypt
import 'package:encrypt/encrypt.dart';
Encrypter
withAESMode.cbc
, because I see that you are using it.final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
IV
using one of the constructor options from the documentation of IV class.Encrypted
instance of your received string from Laravel using one of the constructors from the documentation Encrypted class.Encrypted
andIV
instances you just created:final decrypted = encrypter.decrypt(encrypted, iv: iv);
I hope this helps.
As noted in the comments, you need to discover how the key is derived in
Crypt
.Once you have solved that, in
pointycastle
you will almost certainly need to wrap the CBC cipher in a PKCS7 padding cipher (or you will have to remove the padding yourself). It also handles the block-by-block processing for you. Your Dart code foraesCbcDecrypt
simplifies to: