PBE Encryption/Decryption

36+ Algos PBKDF2 AES/DES
Anish Nath
PBE Encrypt/Decrypt
Message
35 chars | 6 words
Password
Rounds
Algorithm (Ctrl+click for multiple)
Result

Encryption result will appear here

Enter a message and password, then click Encrypt
Processing...

Processing...

OpenSSL PBE Commands
Encrypt with PBE (AES-256-CBC)
# Encrypt file using PBKDF2 with 10000 iterations
$ openssl enc -aes-256-cbc -salt -pbkdf2 -iter 10000 \
-in plaintext.txt -out encrypted.enc
Decrypt with PBE (AES-256-CBC)
# Decrypt file using same parameters
$ openssl enc -aes-256-cbc -d -pbkdf2 -iter 10000 \
-in encrypted.enc -out decrypted.txt
Encrypt with Base64 Output
# Encrypt with Base64 encoded output
$ openssl enc -aes-256-cbc -salt -pbkdf2 -base64 \
-in plaintext.txt -out encrypted.b64
PBKDF2 Key Derivation
# Derive key using PBKDF2 (OpenSSL 3.0+)
$ openssl kdf -keylen 32 -kdfopt digest:SHA256 \
-kdfopt pass:password -kdfopt salt:hex:0102030405060708 \
-kdfopt iter:10000 PBKDF2
Code Samples
PBE Encryption/Decryption - Java (Jasypt)
import org.jasypt.util.text.AES256TextEncryptor;

public class PBEExample {
    public static void main(String[] args) {
        // Using Jasypt for simple PBE
        AES256TextEncryptor encryptor = new AES256TextEncryptor();
        encryptor.setPassword("mySecretPassword");

        // Encrypt
        String plainText = "Hello, World!";
        String encrypted = encryptor.encrypt(plainText);
        System.out.println("Encrypted: " + encrypted);

        // Decrypt
        String decrypted = encryptor.decrypt(encrypted);
        System.out.println("Decrypted: " + decrypted);
    }
}

// Using standard Java Crypto API
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.spec.*;

public class PBEStandard {
    public static byte[] encrypt(String password, String plainText,
                                  int iterations) throws Exception {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16];
        random.nextBytes(salt);

        SecretKeyFactory factory = SecretKeyFactory
            .getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(password.toCharArray(),
                                       salt, iterations, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, secret);
        byte[] iv = cipher.getIV();
        byte[] cipherText = cipher.doFinal(plainText.getBytes("UTF-8"));

        // Combine salt + iv + ciphertext
        ByteBuffer buffer = ByteBuffer.allocate(
            salt.length + iv.length + cipherText.length);
        buffer.put(salt).put(iv).put(cipherText);
        return buffer.array();
    }
}
PBE Encryption/Decryption - Python
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os
import base64

def pbe_encrypt(password: str, plaintext: str, iterations: int = 10000) -> str:
    """Encrypt plaintext using password-based encryption."""
    # Generate random salt and IV
    salt = os.urandom(16)
    iv = os.urandom(16)

    # Derive key using PBKDF2
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=salt,
        iterations=iterations,
        backend=default_backend()
    )
    key = kdf.derive(password.encode())

    # Encrypt using AES-256-CBC
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv),
                    backend=default_backend())
    encryptor = cipher.encryptor()

    # Pad plaintext to block size
    padded = _pad(plaintext.encode())
    ciphertext = encryptor.update(padded) + encryptor.finalize()

    # Combine salt + iv + ciphertext and encode
    result = salt + iv + ciphertext
    return base64.b64encode(result).decode()

def pbe_decrypt(password: str, encrypted: str, iterations: int = 10000) -> str:
    """Decrypt ciphertext using password-based encryption."""
    data = base64.b64decode(encrypted)
    salt, iv, ciphertext = data[:16], data[16:32], data[32:]

    # Derive key using PBKDF2
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=salt,
        iterations=iterations,
        backend=default_backend()
    )
    key = kdf.derive(password.encode())

    # Decrypt
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv),
                    backend=default_backend())
    decryptor = cipher.decryptor()
    padded = decryptor.update(ciphertext) + decryptor.finalize()

    return _unpad(padded).decode()

def _pad(data: bytes) -> bytes:
    padding_len = 16 - (len(data) % 16)
    return data + bytes([padding_len] * padding_len)

def _unpad(data: bytes) -> bytes:
    return data[:-data[-1]]

# Usage
encrypted = pbe_encrypt("myPassword", "Hello, World!")
print(f"Encrypted: {encrypted}")

decrypted = pbe_decrypt("myPassword", encrypted)
print(f"Decrypted: {decrypted}")
PBE Encryption/Decryption - Node.js
const crypto = require('crypto');

class PBECrypto {
    constructor(iterations = 10000) {
        this.iterations = iterations;
        this.keyLength = 32;
        this.algorithm = 'aes-256-cbc';
    }

    encrypt(password, plaintext) {
        // Generate random salt and IV
        const salt = crypto.randomBytes(16);
        const iv = crypto.randomBytes(16);

        // Derive key using PBKDF2
        const key = crypto.pbkdf2Sync(
            password, salt, this.iterations, this.keyLength, 'sha256'
        );

        // Encrypt
        const cipher = crypto.createCipheriv(this.algorithm, key, iv);
        let encrypted = cipher.update(plaintext, 'utf8', 'base64');
        encrypted += cipher.final('base64');

        // Combine salt + iv + ciphertext
        const result = Buffer.concat([
            salt, iv, Buffer.from(encrypted, 'base64')
        ]);

        return result.toString('base64');
    }

    decrypt(password, encryptedData) {
        const data = Buffer.from(encryptedData, 'base64');

        // Extract salt, iv, and ciphertext
        const salt = data.slice(0, 16);
        const iv = data.slice(16, 32);
        const ciphertext = data.slice(32);

        // Derive key using PBKDF2
        const key = crypto.pbkdf2Sync(
            password, salt, this.iterations, this.keyLength, 'sha256'
        );

        // Decrypt
        const decipher = crypto.createDecipheriv(this.algorithm, key, iv);
        let decrypted = decipher.update(ciphertext, 'base64', 'utf8');
        decrypted += decipher.final('utf8');

        return decrypted;
    }
}

// Usage
const pbe = new PBECrypto(10000);

const encrypted = pbe.encrypt('myPassword', 'Hello, World!');
console.log('Encrypted:', encrypted);

const decrypted = pbe.decrypt('myPassword', encrypted);
console.log('Decrypted:', decrypted);
PBE Encryption/Decryption - C#
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class PBECrypto
{
    private readonly int _iterations;

    public PBECrypto(int iterations = 10000)
    {
        _iterations = iterations;
    }

    public string Encrypt(string password, string plaintext)
    {
        byte[] salt = new byte[16];
        byte[] iv = new byte[16];

        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(salt);
            rng.GetBytes(iv);
        }

        // Derive key using PBKDF2
        using var keyDerive = new Rfc2898DeriveBytes(
            password, salt, _iterations, HashAlgorithmName.SHA256);
        byte[] key = keyDerive.GetBytes(32);

        // Encrypt using AES
        using var aes = Aes.Create();
        aes.Key = key;
        aes.IV = iv;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        using var encryptor = aes.CreateEncryptor();
        byte[] plainBytes = Encoding.UTF8.GetBytes(plaintext);
        byte[] cipherBytes = encryptor.TransformFinalBlock(
            plainBytes, 0, plainBytes.Length);

        // Combine salt + iv + ciphertext
        byte[] result = new byte[salt.Length + iv.Length + cipherBytes.Length];
        Buffer.BlockCopy(salt, 0, result, 0, salt.Length);
        Buffer.BlockCopy(iv, 0, result, salt.Length, iv.Length);
        Buffer.BlockCopy(cipherBytes, 0, result,
                         salt.Length + iv.Length, cipherBytes.Length);

        return Convert.ToBase64String(result);
    }

    public string Decrypt(string password, string encrypted)
    {
        byte[] data = Convert.FromBase64String(encrypted);

        byte[] salt = new byte[16];
        byte[] iv = new byte[16];
        byte[] cipherBytes = new byte[data.Length - 32];

        Buffer.BlockCopy(data, 0, salt, 0, 16);
        Buffer.BlockCopy(data, 16, iv, 0, 16);
        Buffer.BlockCopy(data, 32, cipherBytes, 0, cipherBytes.Length);

        using var keyDerive = new Rfc2898DeriveBytes(
            password, salt, _iterations, HashAlgorithmName.SHA256);
        byte[] key = keyDerive.GetBytes(32);

        using var aes = Aes.Create();
        aes.Key = key;
        aes.IV = iv;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        using var decryptor = aes.CreateDecryptor();
        byte[] plainBytes = decryptor.TransformFinalBlock(
            cipherBytes, 0, cipherBytes.Length);

        return Encoding.UTF8.GetString(plainBytes);
    }
}

// Usage
var pbe = new PBECrypto(10000);
string encrypted = pbe.Encrypt("myPassword", "Hello, World!");
Console.WriteLine($"Encrypted: {encrypted}");

string decrypted = pbe.Decrypt("myPassword", encrypted);
Console.WriteLine($"Decrypted: {decrypted}");
PBE Encryption/Decryption - Go
package main

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "crypto/sha256"
    "encoding/base64"
    "fmt"
    "golang.org/x/crypto/pbkdf2"
)

const (
    saltSize   = 16
    ivSize     = 16
    keySize    = 32
    iterations = 10000
)

func Encrypt(password, plaintext string) (string, error) {
    // Generate random salt and IV
    salt := make([]byte, saltSize)
    if _, err := rand.Read(salt); err != nil {
        return "", err
    }

    iv := make([]byte, ivSize)
    if _, err := rand.Read(iv); err != nil {
        return "", err
    }

    // Derive key using PBKDF2
    key := pbkdf2.Key([]byte(password), salt, iterations, keySize, sha256.New)

    // Create AES cipher
    block, err := aes.NewCipher(key)
    if err != nil {
        return "", err
    }

    // Pad plaintext
    plainBytes := pad([]byte(plaintext), aes.BlockSize)

    // Encrypt
    ciphertext := make([]byte, len(plainBytes))
    mode := cipher.NewCBCEncrypter(block, iv)
    mode.CryptBlocks(ciphertext, plainBytes)

    // Combine salt + iv + ciphertext
    result := append(salt, iv...)
    result = append(result, ciphertext...)

    return base64.StdEncoding.EncodeToString(result), nil
}

func Decrypt(password, encrypted string) (string, error) {
    data, err := base64.StdEncoding.DecodeString(encrypted)
    if err != nil {
        return "", err
    }

    salt := data[:saltSize]
    iv := data[saltSize : saltSize+ivSize]
    ciphertext := data[saltSize+ivSize:]

    // Derive key using PBKDF2
    key := pbkdf2.Key([]byte(password), salt, iterations, keySize, sha256.New)

    // Create AES cipher
    block, err := aes.NewCipher(key)
    if err != nil {
        return "", err
    }

    // Decrypt
    plaintext := make([]byte, len(ciphertext))
    mode := cipher.NewCBCDecrypter(block, iv)
    mode.CryptBlocks(plaintext, ciphertext)

    // Unpad
    plaintext = unpad(plaintext)

    return string(plaintext), nil
}

func pad(data []byte, blockSize int) []byte {
    padding := blockSize - (len(data) % blockSize)
    padBytes := make([]byte, padding)
    for i := range padBytes {
        padBytes[i] = byte(padding)
    }
    return append(data, padBytes...)
}

func unpad(data []byte) []byte {
    padding := int(data[len(data)-1])
    return data[:len(data)-padding]
}

func main() {
    encrypted, _ := Encrypt("myPassword", "Hello, World!")
    fmt.Println("Encrypted:", encrypted)

    decrypted, _ := Decrypt("myPassword", encrypted)
    fmt.Println("Decrypted:", decrypted)
}

Support This Free Tool

Every coffee helps keep the servers running. Every book sale funds the next tool I'm dreaming up. You're not just supporting a site — you're helping me build what developers actually need.

500K+ users
200+ tools
100% private
Privacy Guarantee: Private keys you enter or generate are never stored on our servers. All tools are served over HTTPS.
Understanding Password-Based Encryption
What is PBE?

Password-Based Encryption (PBE) is specified in PKCS#5 (RFC 2898). It allows encryption using a password instead of a cryptographic key, making it user-friendly while maintaining security.

How PBE Works
1. Password
User provides a memorable password
2. Salt
Random salt prevents rainbow table attacks
3. Iterations
Multiple rounds slow brute-force attacks
4. Encryption
Derived key encrypts the message
Algorithm Naming Convention

PBE algorithm names follow a pattern: PBEWith[HMAC][Hash]And[Cipher]

Component Options Recommendation
Hash Function MD5, SHA1, SHA256, SHA384, SHA512 SHA256+
Cipher DES, 3DES, AES-128, AES-192, AES-256, RC2, RC4, Twofish, IDEA AES-256
Mode CBC (Cipher Block Chaining) CBC
Security Recommendations
Recommended:
  • PBEWITHHMACSHA256ANDAES_256
  • PBEWITHHMACSHA512ANDAES_256
  • PBEWITHSHA256AND256BITAES-CBC-BC
  • Use 10,000+ iterations minimum
Avoid (Legacy):
  • PBEWITHMD5ANDDES (weak hash + cipher)
  • PBEWITHSHA1ANDRC4_40 (weak cipher)
  • Any algorithm with DES or MD5
  • Low iteration counts (<1000)
Tip: For new applications, consider using Argon2 or scrypt instead of PBKDF2, as they provide better resistance against GPU-based attacks.