skip to Main Content

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


  1. 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:

    1. Install the package:

    flutter pub add encrypt

    1. Import the package:

    import 'package:encrypt/encrypt.dart';

    1. Create an instance of Encrypter with AESMode.cbc, because I see that you are using it.

    final encrypter = Encrypter(AES(key, mode: AESMode.cbc));

    1. Create an IV using one of the constructor options from the documentation of IV class.
    2. Create an Encrypted instance of your received string from Laravel using one of the constructors from the documentation Encrypted class.
    3. Call the decrypt function using the Encrypted and IV instances you just created:

    final decrypted = encrypter.decrypt(encrypted, iv: iv);

    I hope this helps.

    Login or Signup to reply.
  2. 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 for aesCbcDecrypt simplifies to:

      final cipher = PaddedBlockCipherImpl(
        PKCS7Padding(),
        CBCBlockCipher(AESEngine()),
      )..init(
        false, // decrypt
        PaddedBlockCipherParameters(
          ParametersWithIV(KeyParameter(key), iv),
          null,
        ),
      );
    
      // a single call to process converts the ciphertext to plaintext (and removes the padding)
      final pt = cipher.process(ct);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search