AES Encryption/Decryption not giving a expect result for specific bytes

AES encryption/decryption issue for specific input lengths (23 vs 24 bytes) in PHP

I’m using a custom AES implementation in PHP:

PHP

$Cipher = new AESCipher(AES::AES192);

Problem

Two similar inputs behave differently:

CvwCvw-2-2@{}#%~[]=,-_! → working (23 bytes)

CTPView-2-2@{}#%~[]=,-_! → not working (24 bytes)

Encryption works, but decryption fails for the second input.

What I observed

AES uses 16-byte blocks encryption not each character encryption. So, After the 16-byte blocks separation remaining bytes are filled with padding bytes for the 16-byte blocks.

  • 23 bytes → padding = 9 bytes
  • 24 bytes → padding = 8 bytes

So only the padding differs, but results are inconsistent.

What I tried (no success)

  • Switched AES-192 → AES-256
  • Used base64_encode / decode
  • Used rawurlencode / rawurldecode
  • Trimmed input / removed hidden characters
  • Verified INI storage and retrieval

Question

Why would a custom AES implementation fail for certain input sizes (e.g., 24 bytes) but work for others, even though padding should handle both cases?

Is this due to incorrect padding or internal block processing?

@deepak is there a reason why you are using a CUSTOM AES implementation?

Are you able to try (test with) PHP’s native, highly optimized, and secure openssl_encrypt() and openssl_decrypt() functions?

More information at PHP: openssl_encrypt - Manual and PHP: openssl_decrypt - Manual

and then openssl_get_cipher-methods() allows you to pick from a long list of cipher methods, including

  • "aes-192-cbc" (Cipher Block Chaining, which requires proper PKCS#7 padding handled automatically by OpenSSL)

  • "aes-192-ctr" (Counter mode, which turns the block cipher into a stream cipher and eliminates the need for padding entirely)

  • "aes-192-gcm" (Galois/Counter Mode, providing both encryption and authentication/integrity checking)

More info at PHP: openssl_get_cipher_methods - Manual

Hope that helps,
Tony