Get your own Node server
const crypto = require('crypto');

// Generate key and IV
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);

// Data to encrypt
const plainText = 'This is a test message';

// First encrypt with disabled auto padding
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
cipher.setAutoPadding(false);

// Manually pad to block size (16 bytes for AES)
function padToBlockSize(text, blockSize = 16) {
  const padLength = blockSize - (text.length % blockSize);
  return text + '\0'.repeat(padLength);
}

// Encrypt manually padded data
const paddedText = padToBlockSize(plainText);
let encrypted = cipher.update(paddedText, 'utf8', 'hex');
encrypted += cipher.final('hex');

// Now decrypt with auto padding disabled
function decryptWithPadding(encryptedText, usePadding) {
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  decipher.setAutoPadding(usePadding);
  
  try {
    let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
  } catch (error) {
    return `Error: ${error.message}`;
  }
}

// With auto padding (default)
console.log('With auto padding:', decryptWithPadding(encrypted, true));

// Without auto padding (will include padding bytes)
const manualDecrypted = decryptWithPadding(encrypted, false);
console.log('Without auto padding:', manualDecrypted);

// Manually remove padding (trim null bytes)
function removeNullPadding(paddedText) {
  return paddedText.replace(/\0+$/, '');
}

console.log('With manual padding removal:', removeNullPadding(manualDecrypted));

              
With auto padding: This is a test message
Without auto padding: This is a test message\0\0\0\0\0\0\0\0\0\0\0
With manual padding removal: This is a test message