requests-pkcs12
The requests-pkcs12 library extends the popular Python `requests` library to add native support for client-side PKCS#12 (often .p12 or .pfx) certificates. It provides a clean implementation by creating a custom `TransportAdapter` and `SSLContext`, avoiding monkey patching or the use of unencrypted temporary files. Currently at version 1.27, it serves as a robust transitional solution until `requests` incorporates direct PKCS#12 support. The project appears to be actively maintained, with frequent updates.
Warnings
- gotcha Do not combine `pkcs12_filename` or `pkcs12_data` arguments with the standard `requests` `cert` parameter. The `Pkcs12Adapter` handles both certificate and key internally; using `cert` simultaneously can lead to conflicts or incorrect behavior.
- gotcha While `requests-pkcs12` handles client certificate authentication, proper server-side certificate verification (via the `verify` parameter) is still crucial. Failing to set `verify=True` (or providing a CA bundle) can leave your application vulnerable to Man-in-the-Middle attacks.
- deprecated The `requests-pkcs12` library is explicitly stated as a 'transitional solution' by its authors. Future versions of the main `requests` library might eventually incorporate native PKCS#12 support, potentially deprecating the need for this external library.
- gotcha `requests-pkcs12` depends on `cryptography`, which has evolving Python version support. For instance, `cryptography` versions 44.0.0+ (released November 2024) deprecated Python 3.7 support. Ensure your Python environment meets `cryptography`'s and `requests-pkcs12`'s minimum requirements.
Install
-
pip install requests-pkcs12
Imports
- get
from requests_pkcs12 import get
- post
from requests_pkcs12 import post
- Pkcs12Adapter
from requests_pkcs12 import Pkcs12Adapter
- Session
from requests import Session
Quickstart
import os
from requests import Session
from requests_pkcs12 import Pkcs12Adapter, get
# --- Example 1: Simple one-off request ---
# Requires a client certificate file (e.g., clientcert.p12) and its password.
# Ensure 'pkcs12_filename' points to a valid .p12 file
# and 'pkcs12_password' is correct for testing.
PKCS12_FILENAME = os.environ.get('PKCS12_FILENAME', 'clientcert.p12') # Placeholder
PKCS12_PASSWORD = os.environ.get('PKCS12_PASSWORD', 'your_pkcs12_password') # Placeholder
TARGET_URL = os.environ.get('TARGET_URL', 'https://example.com/secure_endpoint') # Placeholder
try:
print(f"\nAttempting one-off GET to {TARGET_URL}...")
r = get(
TARGET_URL,
pkcs12_filename=PKCS12_FILENAME,
pkcs12_password=PKCS12_PASSWORD,
verify=True # Always verify server certificates in production!
)
r.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
print(f"One-off GET successful! Status: {r.status_code}")
# print(r.text)
except Exception as e:
print(f"One-off GET failed: {e}")
# --- Example 2: Using with a requests Session (recommended for multiple requests) ---
try:
print(f"\nAttempting session-based GET to {TARGET_URL}...")
with Session() as s:
s.mount(
'https://',
Pkcs12Adapter(
pkcs12_filename=PKCS12_FILENAME,
pkcs12_password=PKCS12_PASSWORD
)
)
# The 'verify' parameter can be set on the session or per request.
# It is crucial for verifying the server's identity.
r_session = s.get(TARGET_URL, verify=True)
r_session.raise_for_status()
print(f"Session-based GET successful! Status: {r_session.status_code}")
# print(r_session.text)
except Exception as e:
print(f"Session-based GET failed: {e}")
# Note: For actual testing, replace 'clientcert.p12' and 'your_pkcs12_password'
# with a real PKCS#12 file path and its password. You might need a dummy
# server that requires client certificate authentication for full testing.