Encryption using AES/CBC/PKCS5Padding

32x32

Michael Agbenyegah July 25, 2023

AES/CBC/PKCS5Padding Encryption

Let's look at AES (Advanced Encryption Standard) algorithm with CBC (Cipher Block Chaining) mode and PKCS5Padding padding to perform encryption in different programming languages.

We also assume your iv(secret) and key are in base64:

var username = "SYSADMIN";
var password = "3528DD48Z87D4J4F03PA72EXCF36C87E4C64";
var key = "P8euR4Ugt3RTcb+dNjNREmTC4N0RBMYZxsqB+r/oxi0=";
var secret = "K7pnqQRCmOEDdOMpN+ujCQ==";

A web service requires me to encrypt a password using AES by first combining the username and password using a semicolon as separator and convert to base64. Let's look at how this will be done in different languages.

It also requires that the final output after encryption should be converted to base64.

CSharp

var b64UsernamePassword = Base64Encode($"{username}:{password}");

var key_ = Convert.FromBase64String(key);
var secret_ = Convert.FromBase64String(secret);
var encryptedPassword = Convert.ToBase64String(AesEncrypt(b64UsernamePassword, key_, secret_));
public string Base64Encode(string plainText)
{
    var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
    return Convert.ToBase64String(plainTextBytes);
}
public byte[] AesEncrypt(string plainText, byte[] Key, byte[] IV)
{
    byte[] encrypted;   
    using (AesManaged aes = new AesManaged())
    {   
        ICryptoTransform encryptor = aes.CreateEncryptor(Key, IV); 
        using (MemoryStream ms = new MemoryStream())
        { 
            using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
            {   
                using (StreamWriter sw = new StreamWriter(cs))
                sw.Write(plainText);
                encrypted = ms.ToArray();
            }
        }
    }
    return encrypted;
}    

Java

String b64UsernamePassword = Base64.getEncoder().encodeToString((username.concat(":").concat(password)).getBytes());

//keys are in base64
byte[] byteKey = Base64.getDecoder().decode(key);
byte[] byteSecret = Base64.getDecoder().decode(secret);
byte[] encryptedPassword;

try {
    encryptedPassword = AesEncrypt(b64UsernamePassword,byteKey,byteSecret);
} catch (NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException | InvalidKeyException |
         InvalidAlgorithmParameterException | IllegalBlockSizeException | IOException e) {
    throw new RuntimeException(e);
}

//Convert encryptedPassword to base64
var finalEncryptedPassword = Base64.getEncoder().encodeToString(encryptedPassword);
public static byte[] AesEncrypt(String plainText, byte[] key, byte[] iv) throws NoSuchAlgorithmException,
    NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException,
    BadPaddingException, IOException {

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

byte[] plainTextBytes = plainText.getBytes(StandardCharsets.UTF_8);
return cipher.doFinal(plainTextBytes);
}