Registry / auth-security / dkimpy

dkimpy

JSON →
library1.1.8pypypi✓ verified 87d ago

DKIMpy is a Python library for creating and verifying DKIM (DomainKeys Identified Mail), ARC (Authenticated Receive Chain), and TLSRPT (TLS Report) signatures on email messages. It provides a robust implementation for email authentication, relying on cryptographic operations and DNS lookups. The current version is 1.1.8, and it maintains a stable release cadence with updates addressing security and compatibility.

pip install dkimpy
INSTALL
IMPORT
SIG · DKIMPY
D
dkimpy
auth-securitypythonv1.1.8
Install
2.7s avg
Import
—
Disk
20MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.9–3.13
musl
3.9–3.13
Install & Compatibility
Where this runs
tested against v1.1.8 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.10–3.915 runs
installs and imports cleanly · install 0.0s · import 0.000s · 22MB
glibc
py 3.10–3.915 runs
installs and imports cleanly · install 2.7s · import 0.000s · 22MB
20MB installed
● package 20MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

DKIM
✓ from dkim import DKIM
✗ from dkimpy.dkim import DKIM

This quickstart demonstrates how to sign an email using `dkimpy.dkim.DKIM` and how to initiate verification using `dkimpy.dkim.verify`. For actual signing, a private key (bytes) and a domain/selector (bytes) are required. Full verification relies on accurate DNS TXT records for the public key, which `dkimpy` will query automatically.

import os from dkimpy.dkim import DKIM, verify, DKIMException # In a real application, load your actual private key and use your domain/selector. # Example key generation (using openssl): # openssl genrsa -out dkim.private 1024 # openssl rsa -in dkim.private -pubout -out dkim.public # Then load: `with open('dkim.private', 'rb') as f: private_key = f.read()` private_key = os.environ.get('DKIM_PRIVATE_KEY', b"") # Should be bytes domain = os.environ.get('DKIM_DOMAIN', 'example.com') selector = os.environ.get('DKIM_SELECTOR', 's1') # Sample email content (bytes) - DKIMpy works with byte strings email_message_bytes = b"""From: sender@example.com\r\nTo: recipient@example.com\r\nSubject: Test DKIM Signature\r\n\r\nThis is the body of the email.\r\n""" # --- 1. Sign an email --- print("--- Signing an Email ---") if not private_key: print("Warning: DKIM_PRIVATE_KEY environment variable not set. Signing will likely fail.") print("Please provide a valid private key for real signing.") try: # Initialize the DKIM signer signer = DKIM( message=email_message_bytes, selector=selector.encode(), # Selector must be bytes domain=domain.encode(), # Domain must be bytes privkey=private_key ) # Sign the message signed_email_bytes = signer.sign() print("Email signed successfully. First 500 bytes of signed email:") print(signed_email_bytes[:500].decode(errors='ignore')) print("...") except DKIMException as e: print(f"Error signing email: {e}") except Exception as e: print(f"An unexpected error occurred during signing: {e}") # --- 2. Verify a received email --- # For actual verification, the signed email needs to be received, and # dkimpy will perform DNS lookups for the public key (TXT record). print("\n--- Verification Example (requires real signed email and DNS) ---") received_signed_email_bytes = signed_email_bytes # Use the just-signed email for demonstration try: # The `verify` function is a module-level function # It returns a list of (dkim_domain, dkim_selector, ...) tuples for each valid signature. result = verify(received_signed_email_bytes) if result: print(f"Verification successful. Found {len(result)} valid DKIM signatures.") # print(f"Result details: {result}") # Uncomment for verbose output else: print("Verification failed or no valid DKIM-Signature found.") except DKIMException as e: print(f"Verification encountered an error: {e}") except Exception as e: print(f"An unexpected error occurred during verification: {e}")
dkimpy --version
Debug
Known issues
breakingVersion 1.0.0 introduced a major rewrite, making it incompatible with Python 2. Code written for `dkimpy` prior to 1.0.0 will likely break when upgrading to Python 3 with `dkimpy>=1.0.0`.
fix
Migrate your code to Python 3 and update call signatures and data types (e.g., using byte strings for email content and keys instead of unicode).
affects: <1.0.0
gotchaAll email content, keys, domain, and selector parameters must be byte strings (`bytes`), not unicode strings (`str`). Passing `str` will lead to `TypeError` or unexpected encoding issues.
fix
Ensure all string-like inputs are explicitly encoded to bytes using `.encode('utf-8')` or similar, e.g., `b'example.com'`, `b's1'`.
affects: >=1.0.0
gotchaDKIM verification heavily relies on successful DNS lookups to retrieve the public key. Network issues, misconfigured DNS records (TXT records), or DNSSEC failures can cause verification to fail.
fix
Ensure your environment has working DNS resolution. For verification failures, check the domain's DKIM DNS TXT records (`selector._domainkey.example.com`) and confirm they contain a valid public key (p= tag).
affects: All
gotchaThe private key must be in PEM format. Other formats (e.g., DER) are not directly supported and will result in `cryptography.exceptions.InvalidKey` or other decryption errors.
fix
Ensure your private key is in PEM format. You can often convert keys using `openssl` if needed.
affects: All
Upgrade
Version history
1.1.8latest on PyPI · released Jul 4, 2024
Audit
Dependencies
cryptographyrequiredCore cryptographic operations for signing and verification.
dnspythonrequiredRequired for performing DNS lookups to retrieve public keys during verification.
pycryptodomexrequiredProvides additional cryptographic primitives.
authresoptionalOften used alongside DKIM for generating Authentication-Results headers.
Agent activity
33 hits · last 30 days
node
30
OpenAI (training)
1
Resources
dkimpy — pip install dkimpy · libregistry