Skip to main content

devolutions-crypto

PyPI version Python versions

Cryptographic library used in Devolutions products. It is made to be fast, easy to use and misuse-resistant.

This is the official Python wrapper for the devolutions-crypto Rust library, providing high-performance cryptographic operations with a simple, Pythonic API.

Installation

pip install devolutions-crypto

Features

  • Symmetric Encryption: Fast AES-256-GCM encryption for shared-key scenarios
  • Asymmetric Encryption: X25519-based public-key encryption
  • Password Hashing: Secure password hashing with Argon2 and PBKDF2
  • Digital Signatures: Ed25519 signatures for data authentication
  • Key Derivation: Argon2 and PBKDF2 key derivation functions
  • Type Safety: Full type hints and IDE support

Quick Start

import devolutions_crypto
import os

# Generate a random encryption key
key = os.urandom(32)

# Encrypt some data
plaintext = b"Hello, World!"
ciphertext = devolutions_crypto.encrypt(plaintext, key)

# Decrypt it back
decrypted = devolutions_crypto.decrypt(ciphertext, key)
assert decrypted == plaintext

Usage Examples

Table of Contents

Symmetric Encryption

Use symmetric encryption when both parties share the same secret key.

import devolutions_crypto
import os

# Generate a 32-byte encryption key
key = os.urandom(32)

# Encrypt data
plaintext = b"This is secret data"
ciphertext = devolutions_crypto.encrypt(plaintext, key)

# Decrypt data
decrypted = devolutions_crypto.decrypt(ciphertext, key)
assert decrypted == plaintext

With Additional Authenticated Data (AAD)

AAD allows you to bind additional context to the ciphertext without encrypting it:

import devolutions_crypto
import os

key = os.urandom(32)
plaintext = b"Secret message"
aad = b"user_id:12345"  # Context data (not encrypted, but authenticated)

# Encrypt with AAD
ciphertext = devolutions_crypto.encrypt_with_aad(plaintext, key, aad)

# Decrypt with AAD (must match encryption AAD)
decrypted = devolutions_crypto.decrypt_with_aad(ciphertext, key, aad)
assert decrypted == plaintext

# Decryption fails with wrong or missing AAD
try:
    devolutions_crypto.decrypt_with_aad(ciphertext, key, b"wrong_context")
except devolutions_crypto.DevolutionsCryptoError:
    print("Authentication failed - AAD mismatch")

Asymmetric Encryption

Use asymmetric encryption when you want to encrypt data for a recipient using their public key.

import devolutions_crypto

# Generate a keypair
keypair = devolutions_crypto.generate_keypair()

# Encrypt data with the public key
plaintext = b"Secret message for Bob"
ciphertext = devolutions_crypto.encrypt_asymmetric(plaintext, keypair.public_key)

# Decrypt with the private key
decrypted = devolutions_crypto.decrypt_asymmetric(ciphertext, keypair.private_key)
assert decrypted == plaintext

Key Exchange Example

Alice and Bob can establish a shared secret without transmitting it:

import devolutions_crypto

# Alice generates her keypair
alice_keypair = devolutions_crypto.generate_keypair()

# Bob generates his keypair
bob_keypair = devolutions_crypto.generate_keypair()

# They exchange public keys (public keys can be transmitted over insecure channels)

# Alice encrypts a message for Bob using his public key
message = b"Hello Bob!"
ciphertext = devolutions_crypto.encrypt_asymmetric(message, bob_keypair.public_key)

# Bob decrypts the message using his private key
decrypted = devolutions_crypto.decrypt_asymmetric(ciphertext, bob_keypair.private_key)
assert decrypted == message

Password Hashing

Securely hash and verify passwords. The default uses Argon2id:

import devolutions_crypto

# Hash a password (this is slow by design)
password = b"my_secure_password123!"
password_hash = devolutions_crypto.hash_password(password)

# Verify the password
is_valid = devolutions_crypto.verify_password(password, password_hash)
assert is_valid is True

# Wrong password fails verification
is_valid = devolutions_crypto.verify_password(b"wrong_password", password_hash)
assert is_valid is False

Digital Signatures

Sign data to prove authenticity and verify signatures:

Generating a Signing Keypair

import devolutions_crypto

# Generate a signing keypair
signing_keypair = devolutions_crypto.generate_signing_keypair()

# Extract the public key
public_key = signing_keypair.get_public_key()

Signing Data

import devolutions_crypto

# Sign some data
data = b"This is an important message"
signature = devolutions_crypto.sign(data, signing_keypair.get_private_key())

Verifying Signatures

import devolutions_crypto

# Verify the signature with the public key
is_valid = devolutions_crypto.verify_signature(data, public_key, signature)
assert is_valid is True

# Verification fails for modified data
modified_data = b"This is a tampered message"
is_valid = devolutions_crypto.verify_signature(modified_data, public_key, signature)
assert is_valid is False

Key Derivation

Derive cryptographic keys from passwords or other key material.

PBKDF2

import devolutions_crypto
import os

# Derive a key from a password
password = b"user_password"
salt = os.urandom(16)  # Use a unique random salt per user

derived_key = devolutions_crypto.derive_key_pbkdf2(
    password,
    salt=salt,
    iterations=600000,
    length=32
)

# Use the derived key for encryption
plaintext = b"User data"
ciphertext = devolutions_crypto.encrypt(plaintext, derived_key)

Argon2

import devolutions_crypto

# Derive a key using Argon2id
password = b"user_password"
parameters = devolutions_crypto.Argon2ParametersBuilder().build()  # default Argon2id parameters
derived_key = devolutions_crypto.derive_key_argon2(password, parameters)

Password-Based Encryption

Encrypt data directly with a password. The key is derived with Argon2id and the derivation parameters (including the random salt) are stored in the returned blob, so decryption only needs the password.

import devolutions_crypto

password = b"my_secure_password"
plaintext = b"secret data"

# Encrypt with a password
blob = devolutions_crypto.derive_encrypt_with_password(plaintext, password)

# Decrypt with the same password
decrypted = devolutions_crypto.derive_decrypt_with_password(blob, password)
assert decrypted == plaintext

With Additional Authenticated Data (AAD)

import devolutions_crypto

password = b"my_secure_password"
plaintext = b"secret data"
aad = b"context"

blob = devolutions_crypto.derive_encrypt_with_password_and_aad(plaintext, password, aad)
decrypted = devolutions_crypto.derive_decrypt_with_password_and_aad(blob, password, aad)
assert decrypted == plaintext

# Decryption fails with wrong or missing AAD
try:
    devolutions_crypto.derive_decrypt_with_password(blob, password)
except devolutions_crypto.DevolutionsCryptoError:
    print("Authentication failed - AAD required")

Supported Python Versions

  • Python 3.10+
  • Python 3.11
  • Python 3.12
  • Python 3.13
  • Python 3.14

Supported Platforms

Pre-built wheels are available for:

  • Linux: x86_64, i686, aarch64
  • macOS: x86_64 (Intel), aarch64 (Apple Silicon)
  • Windows: x86, x64, ARM64

Security Notes

  1. Key Management: Always use cryptographically secure random number generators (like os.urandom()) for key generation
  2. Salt Uniqueness: Use unique salts for each password/user when deriving keys
  3. Iterations: Use high iteration counts (100,000+) for password hashing and key derivation
  4. Key Size: Use 32-byte (256-bit) keys for symmetric encryption
  5. AAD: Additional Authenticated Data must match exactly between encryption and decryption

Exception Handling

All functions may raise DevolutionsCryptoError on errors:

import devolutions_crypto

try:
    # Invalid key size
    result = devolutions_crypto.encrypt(b"data", b"short_key")
except devolutions_crypto.DevolutionsCryptoError as e:
    print(f"Encryption error: {e}")

Underlying Algorithms

As of the current version:

  • Symmetric encryption: AES-256-GCM
  • Asymmetric encryption: X25519 (ECDH) + AES-256-GCM (ECIES)
  • Password hashing: PBKDF2-HMAC-SHA256
  • Digital signatures: Ed25519
  • Key derivation: PBKDF2-HMAC-SHA256, Argon2

Performance

This library is built on Rust and compiled to native code, providing excellent performance:

  • Symmetric encryption/decryption: Millions of operations per second
  • Asymmetric operations: Thousands of operations per second
  • Password hashing: Intentionally slow (configurable via iterations)

Contributing

This project is open source. Visit the GitHub repository to report issues or contribute.

License

This project is licensed under MIT OR Apache-2.0.

Metadata

Release files for devolutions-crypto 2026.6.22

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for devolutions-crypto 2026.6.22
File
devolutions_crypto-2026.6.22-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details
devolutions_crypto-2026.6.22-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
devolutions_crypto-2026.6.22-py3-none-win32.whl Python 3 none Windows x86-32 Details
devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_x86_64.whl Python 3 none Linux glibc 2.34+ x86-64 Details
devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_i686.whl Python 3 none Linux glibc 2.34+ x86-32 Details
devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_aarch64.whl Python 3 none Linux glibc 2.34+ ARM64 Details
devolutions_crypto-2026.6.22-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
devolutions_crypto-2026.6.22-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size: 3.9 MB

Release files / devolutions_crypto-2026.6.22-py3-none-win_arm64.whl

Download URL devolutions_crypto-2026.6.22-py3-none-win_arm64.whl
Size 403.4 kB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
652b1714a0a39d601f6171d257879247d87305d5ad99a2699fb0abade70889ad
BLAKE2b-256 checksum
How to use checksums
866ea8394ad9a897dc28ae7bcbd9c74726f7784db467627aae50c5dc337500af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 22, 2026.

Transparency log

Release files / devolutions_crypto-2026.6.22-py3-none-win_amd64.whl

Download URL devolutions_crypto-2026.6.22-py3-none-win_amd64.whl
Size 456.9 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
c0a600438ad933cb385571bb8f20084629d3b2b3471854dd0bacdf58382a1f23
BLAKE2b-256 checksum
How to use checksums
fc976a1222565931765a97844aadaf0f9f1e7ec53fc4a9a0319cf035e7d1e69b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 22, 2026.

Transparency log

Release files / devolutions_crypto-2026.6.22-py3-none-win32.whl

Download URL devolutions_crypto-2026.6.22-py3-none-win32.whl
Size 430.8 kB
Tags Python 3 Windows x86-32
SHA-256 checksum
How to use checksums
b5e8d0b49c2ed43a3dddc6cc9fbd19d0d3ddf977ebd285dd04f093ac0abf9548
BLAKE2b-256 checksum
How to use checksums
40ce22f253808de5d8551fa474c9dd8939d25fd4f4ecf225fcd2aa2410ae62c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 22, 2026.

Transparency log

Release files / devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_x86_64.whl

Download URL devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_x86_64.whl
Size 528.3 kB
Tags Linux glibc 2.34+ x86-64 Python 3
SHA-256 checksum
How to use checksums
4f1d428a41c72b4afde8b16a65b6bf25c32508feb5a42cf9e82ee50c058647a7
BLAKE2b-256 checksum
How to use checksums
349decfb174afdcf5dfa507ebaa18c2004fb73a4ed2b8e7db21253cbe9790263
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 22, 2026.

Transparency log

Release files / devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_i686.whl

Download URL devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_i686.whl
Size 593.0 kB
Tags Linux glibc 2.34+ x86-32 Python 3
SHA-256 checksum
How to use checksums
ef35d8834f2692cfc9c9975109cbe8a4d00f9a91f5310f9c926a0753c183b002
BLAKE2b-256 checksum
How to use checksums
f2882b714695d5dbdc8f1c6e7f975441fe89aca906e203d785b5587c1b02533e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 22, 2026.

Transparency log

Release files / devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_aarch64.whl

Download URL devolutions_crypto-2026.6.22-py3-none-manylinux_2_34_aarch64.whl
Size 507.8 kB
Tags Linux glibc 2.34+ ARM64 Python 3
SHA-256 checksum
How to use checksums
6981f2147fd009a3f6f6159fed8b96902ddab3640d76cf60adc58c5952176e8e
BLAKE2b-256 checksum
How to use checksums
6fc959776fa3a7d267b20c390776f51a8a565a51a8fbdc61c7acdd23cd4fad94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 22, 2026.

Transparency log

Release files / devolutions_crypto-2026.6.22-py3-none-macosx_11_0_arm64.whl

Download URL devolutions_crypto-2026.6.22-py3-none-macosx_11_0_arm64.whl
Size 443.3 kB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b58ed403376441050ea4a527f282bb5ec3ca2fc3682509f66c6440c68cabd6ad
BLAKE2b-256 checksum
How to use checksums
becfe90408e0b039c5ecf246e69e8e8d253b551253033a24b8750e725111150f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 22, 2026.

Transparency log

Release files / devolutions_crypto-2026.6.22-py3-none-macosx_10_12_x86_64.whl

Download URL devolutions_crypto-2026.6.22-py3-none-macosx_10_12_x86_64.whl
Size 502.9 kB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
9b0692a0a55299a9384894919cb5c50392b4cf01167b9c6f7a0e68d25c3cfdba
BLAKE2b-256 checksum
How to use checksums
3ff8997d5ffa5a749c27e1468674901a94b4f500f4d82e5d44153a8a0b6efca4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2026.6.22 This release

8 release files

0.9.2

40 release files

0.9.1

15 release files

0.9.0

15 release files

0.8.0

10 release files

0.7.0

10 release files

0.6.0

10 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page