Skip to main content

Jasypt-compatible PBE encryption and digest for Python

Project description

pysypt

Language Python License: MIT

Jasypt-compatible password-based encryption (PBE) and iterated-hash digest for Python. Interoperable with Spring Boot applications that use ENC(...) encrypted configuration values.

Port of @alt-javascript/jasypt to Python.

Install

uv add pysypt        # or: pip install pysypt

Requires Python 3.12+ and cryptography >= 42.

Quick Start

from pysypt import Jasypt

jasypt = Jasypt()

# Encrypt and decrypt
ciphertext = jasypt.encrypt("admin", "mySecretKey")
plaintext  = jasypt.decrypt(ciphertext, "mySecretKey")
# plaintext == "admin"

# One-way digest
stored = jasypt.digest("admin")
jasypt.matches("admin", stored)  # True
jasypt.matches("wrong", stored)  # False

API

Jasypt

High-level facade. Each method constructs a fresh Encryptor or Digester internally — the Jasypt class is stateless and thread-safe.

jasypt.encrypt(message, password, algorithm="PBEWITHMD5ANDDES", iterations=1000, salt=None)

Encrypts a plaintext string. Returns a base64-encoded ciphertext with the salt prepended.

Returns None if message is empty or None.

jasypt.encrypt("admin", "secret")
# => "nsbC5r0ymz740/aURtuRWw=="

jasypt.encrypt("admin", "secret", algorithm="PBEWITHHMACSHA256ANDAES_256")
# => "K3q8z..."  (AES-256-CBC, PBKDF2-SHA256)

jasypt.decrypt(encrypted_message, password="", algorithm="PBEWITHMD5ANDDES", iterations=1000, salt=None)

Decrypts a base64-encoded ciphertext. The salt is extracted from the ciphertext automatically.

Returns None if encrypted_message is empty or None.

jasypt.decrypt("nsbC5r0ymz740/aURtuRWw==", "secret")
# => "admin"

jasypt.digest(message, salt=None, iterations=1000, algorithm="SHA-256")

Produces a one-way hash. Returns base64(salt_bytes + hash_bytes).

Returns None if message is empty or None.

stored = jasypt.digest("admin")

jasypt.matches(message, stored_digest, salt=None, iterations=1000, algorithm="SHA-256")

Verifies a plaintext message against a stored digest. Uses constant-time comparison.

Returns None if message is empty or None.

stored = jasypt.digest("admin")
jasypt.matches("admin", stored)  # True
jasypt.matches("wrong", stored)  # False

Encryptor

Low-level class for direct control over encryption parameters.

from pysypt import Encryptor

enc = Encryptor(
    algorithm="PBEWITHHMACSHA256ANDAES_256",
    iterations=10000,
)

ciphertext = enc.encrypt("admin", "secret")
plaintext  = enc.decrypt(ciphertext, "secret")

Constructor

Encryptor(algorithm="PBEWITHMD5ANDDES", salt=None, iterations=1000)
Parameter Type Default Description
algorithm str PBEWITHMD5ANDDES PBE algorithm name (see table below)
salt bytes | None random Salt bytes. None generates a random salt of the correct length.
iterations int 1000 KDF iteration count

Methods

Method Description
set_algorithm(algorithm) Change the algorithm. Raises ValueError for unsupported names.
set_salt(salt) Set the salt. Accepts bytes, str (UTF-8 encoded), or None (random). Short salts are zero-padded; long salts are truncated to the required length.
set_iterations(iterations) Set the iteration count.
encrypt(payload, password, salt=None, iterations=None) Encrypt. Returns base64 string.
decrypt(payload, password, iterations=None) Decrypt. Returns plaintext string.

Digester

Low-level class for direct control over digest parameters.

from pysypt import Digester

d = Digester(algorithm="SHA-512", iterations=5000)
d.set_salt("fixedsalt")

stored   = d.digest("admin")
is_match = d.matches("admin", stored)  # True

Constructor

Digester(algorithm="SHA-256", salt=None, iterations=1000)
Parameter Type Default Description
algorithm str SHA-256 Digest algorithm name (see table below)
salt str | None random per digest Fixed salt string. If None, a random 8-byte salt is generated per call.
iterations int 1000 Hash iteration count

Methods

Method Description
set_algorithm(algorithm) Change the algorithm. Raises ValueError for unsupported names.
set_salt(salt) Set a fixed salt.
set_iterations(iterations) Set the iteration count.
digest(message, salt=None, iterations=None) Produce base64(salt + hash).
matches(message, stored_digest, salt=None, iterations=None) Constant-time verification.

Supported Algorithms

Encryption

Algorithm Type Notes
PBEWITHMD5ANDDES PBE1 Default. EVP_BytesToKey KDF + DES-CBC. See ADR-005.
PBEWITHMD5ANDTRIPLEDES PBE1 EVP_BytesToKey KDF + 3DES-CBC
PBEWITHSHA1ANDDESEDE PBE1 EVP_BytesToKey KDF (SHA-1) + 3DES-CBC
PBEWITHHMACSHA1ANDAES_128 PBE2 PBKDF2-SHA1 + AES-128-CBC
PBEWITHHMACSHA1ANDAES_256 PBE2 PBKDF2-SHA1 + AES-256-CBC
PBEWITHHMACSHA224ANDAES_128 PBE2 PBKDF2-SHA224 + AES-128-CBC
PBEWITHHMACSHA224ANDAES_256 PBE2 PBKDF2-SHA224 + AES-256-CBC
PBEWITHHMACSHA256ANDAES_128 PBE2 PBKDF2-SHA256 + AES-128-CBC
PBEWITHHMACSHA256ANDAES_256 PBE2 PBKDF2-SHA256 + AES-256-CBC (recommended)
PBEWITHHMACSHA384ANDAES_128 PBE2 PBKDF2-SHA384 + AES-128-CBC
PBEWITHHMACSHA384ANDAES_256 PBE2 PBKDF2-SHA384 + AES-256-CBC
PBEWITHHMACSHA512ANDAES_128 PBE2 PBKDF2-SHA512 + AES-128-CBC
PBEWITHHMACSHA512ANDAES_256 PBE2 PBKDF2-SHA512 + AES-256-CBC

PBE1 uses an iterative MD5/SHA-1 KDF (EVP_BytesToKey-style) with an 8-byte salt prepended to the ciphertext.

PBE2 uses PBKDF2 with a 16-byte salt and a random 16-byte IV, both prepended to the ciphertext.

RC2 and RC4 variants are not supported — see ADR-006.

Digest

Algorithm Available by default
MD5
SHA-1
SHA-224
SHA-256 ✅ (default)
SHA-384
SHA-512
SHA-512/224
SHA-512/256
SHA3-224
SHA3-256
SHA3-384
SHA3-512
MD2 Rarely available

Digester.SUPPORTED_ALGORITHMS reflects only algorithms available in the current OpenSSL build. Digester.set_algorithm("MD2") raises ValueError if MD2 is unavailable.

Wire Format

Both classes produce self-describing base64 ciphertext — the salt (and IV for PBE2) is stored inline so decryption requires only the password:

PBE1:  base64( salt[8]  + ciphertext )
PBE2:  base64( salt[16] + iv[16]     + ciphertext )
Digest: base64( salt[8]  + hash_bytes )

Java Interoperability

PBE2 algorithms (PBEWITHHMACSHA*ANDAES_*) are fully interoperable with Java jasypt. If you encrypt a value in Java using PBEWITHHMACSHA256ANDAES_256 and the same password, pysypt will decrypt it correctly.

PBE1 DES (PBEWITHMD5ANDDES) is not byte-for-byte compatible with Java due to the TripleDES-EDE emulation (ADR-005). Use a PBE2 algorithm for cross-language scenarios.

Troubleshooting

ValueError: Unsupported algorithm: MYALGO The algorithm name is not in the supported list. Check spelling and case — names must match exactly (e.g. PBEWITHHMACSHA256ANDAES_256).

Decryption produces garbled text The password or algorithm does not match what was used to encrypt. Both the encryptor and decryptor must use the same algorithm and password.

ValueError: Invalid padding bytes The ciphertext is corrupt, truncated, or was encrypted with a different algorithm. This can also occur if the base64 string was URL-encoded and not decoded first.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

alt_python_pysypt-1.1.0.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

alt_python_pysypt-1.1.0-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file alt_python_pysypt-1.1.0.tar.gz.

File metadata

  • Download URL: alt_python_pysypt-1.1.0.tar.gz
  • Upload date:
  • Size: 9.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for alt_python_pysypt-1.1.0.tar.gz
Algorithm Hash digest
SHA256 ba8f5183a962f43571563d34d623e4b8ec53eddabcd04006673cbda3b9e2a437
MD5 4a0328989ecc735ffb4ee60adaaebdc7
BLAKE2b-256 4f1ed60eeb03a44744f855f867e123c81c6e3c0d5ac3720a37fccef14a9fcd75

See more details on using hashes here.

File details

Details for the file alt_python_pysypt-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: alt_python_pysypt-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for alt_python_pysypt-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 91d8d186a888b705fda8e65af8e5cf5fc6f72364878804b288de7af32a056a73
MD5 10f6c872f84ee090479e25ea43aa14ef
BLAKE2b-256 078a94e02026944ec592c0f6596f731072845d3041eae93d0942dcdb6df7267a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page