Public and private key structures for various cryptographic algorithms, along with comprehensive X.509 certificate support. This module provides the core structures for handling cryptographic keys and certificates used in PKI systems.
Structures for representing public keys in various formats and algorithms.
class PublicKeyInfo(core.Sequence):
"""
Subject Public Key Info structure (RFC 5280).
Standard structure for encoding public keys with algorithm information.
Structure:
algorithm: AlgorithmIdentifier - Public key algorithm
publicKey: BIT STRING - The public key data
"""
@property
def algorithm(self):
"""Get the public key algorithm name."""
@property
def public_key(self):
"""Get the public key as bytes."""
@property
def bit_size(self):
"""Get the key size in bits."""
@property
def sha1_fingerprint(self):
"""Get SHA-1 fingerprint of the public key."""
@property
def sha256_fingerprint(self):
"""Get SHA-256 fingerprint of the public key."""
class RSAPublicKey(core.Sequence):
"""
RSA public key structure (RFC 3447).
Structure:
modulus: INTEGER - RSA modulus n
publicExponent: INTEGER - RSA public exponent e
"""
@property
def modulus(self):
"""Get the RSA modulus."""
@property
def public_exponent(self):
"""Get the RSA public exponent."""
@property
def bit_size(self):
"""Get the key size in bits."""Structures for representing private keys with algorithm-specific formats.
class PrivateKeyInfo(core.Sequence):
"""
Private Key Info structure (RFC 5208).
Standard structure for encoding private keys with algorithm information.
Structure:
version: INTEGER - Version (always 0)
privateKeyAlgorithm: AlgorithmIdentifier - Private key algorithm
privateKey: OCTET STRING - The private key data
attributes: Attributes OPTIONAL - Optional attributes
"""
@property
def algorithm(self):
"""Get the private key algorithm name."""
@property
def private_key(self):
"""Get the private key as bytes."""
@property
def bit_size(self):
"""Get the key size in bits."""
@property
def public_key_info(self):
"""Get the corresponding PublicKeyInfo."""
class EncryptedPrivateKeyInfo(core.Sequence):
"""
Encrypted Private Key Info structure (RFC 5208).
Structure for password-protected private keys.
Structure:
encryptionAlgorithm: AlgorithmIdentifier - Encryption algorithm
encryptedData: OCTET STRING - Encrypted private key data
"""
@property
def encryption_algorithm(self):
"""Get the encryption algorithm identifier."""
@property
def encrypted_data(self):
"""Get the encrypted private key data."""
class RSAPrivateKey(core.Sequence):
"""
RSA private key structure (RFC 3447).
Structure:
version: INTEGER - Version (0 for two-prime, 1 for multi-prime)
modulus: INTEGER - RSA modulus n
publicExponent: INTEGER - RSA public exponent e
privateExponent: INTEGER - RSA private exponent d
prime1: INTEGER - First prime factor p
prime2: INTEGER - Second prime factor q
exponent1: INTEGER - d mod (p-1)
exponent2: INTEGER - d mod (q-1)
coefficient: INTEGER - (inverse of q) mod p
"""
@property
def modulus(self):
"""Get the RSA modulus."""
@property
def public_exponent(self):
"""Get the RSA public exponent."""
@property
def private_exponent(self):
"""Get the RSA private exponent."""
@property
def prime1(self):
"""Get the first prime factor."""
@property
def prime2(self):
"""Get the second prime factor."""
class DSAPrivateKey(core.Sequence):
"""
DSA private key structure.
The private key value for DSA algorithms.
"""
class ECPrivateKey(core.Sequence):
"""
Elliptic Curve private key structure (RFC 5915).
Structure:
version: INTEGER - Version (always 1)
privateKey: OCTET STRING - EC private key value
parameters: ECParameters OPTIONAL - EC domain parameters
publicKey: BIT STRING OPTIONAL - EC public key
"""
@property
def private_key(self):
"""Get the EC private key value."""
@property
def public_key(self):
"""Get the EC public key (if present)."""
@property
def parameters(self):
"""Get the EC domain parameters."""Parameter structures for various key algorithms.
class DSAParams(core.Sequence):
"""
DSA algorithm parameters.
Structure:
p: INTEGER - Prime modulus
q: INTEGER - Prime divisor of (p-1)
g: INTEGER - Generator
"""
@property
def p(self):
"""Get the prime modulus."""
@property
def q(self):
"""Get the prime divisor."""
@property
def g(self):
"""Get the generator."""
class ECDomainParameters(core.Choice):
"""
Elliptic Curve domain parameters.
Can specify parameters by:
- Named curve (OBJECT IDENTIFIER)
- Explicit parameters (ECParameters)
- Implicit parameters (NULL)
"""
@property
def name(self):
"""Get the curve name (for named curves)."""Complete X.509 certificate structures and related components.
class Certificate(core.Sequence):
"""
X.509 Certificate structure (RFC 5280).
Structure:
tbsCertificate: TBSCertificate - Certificate information
signatureAlgorithm: AlgorithmIdentifier - Signature algorithm
signature: BIT STRING - Certificate signature
"""
@property
def subject(self):
"""Get the certificate subject name."""
@property
def issuer(self):
"""Get the certificate issuer name."""
@property
def serial_number(self):
"""Get the certificate serial number."""
@property
def not_valid_before(self):
"""Get the validity start date."""
@property
def not_valid_after(self):
"""Get the validity end date."""
@property
def public_key(self):
"""Get the public key info."""
@property
def signature_algorithm(self):
"""Get the signature algorithm."""
@property
def signature(self):
"""Get the signature value."""
@property
def extensions(self):
"""Get the certificate extensions."""
@property
def sha1_fingerprint(self):
"""Get SHA-1 fingerprint of the certificate."""
@property
def sha256_fingerprint(self):
"""Get SHA-256 fingerprint of the certificate."""
@property
def key_usage_value(self):
"""Get key usage extension value."""
@property
def basic_constraints_value(self):
"""Get basic constraints extension value."""
@property
def subject_alt_name_value(self):
"""Get subject alternative name extension value."""
class Name(core.Sequence):
"""
Distinguished Name structure.
Represents X.500 distinguished names used in certificates.
"""
@property
def human_friendly(self):
"""Get human-friendly string representation."""
def __str__(self):
"""Get string representation of the name."""
class GeneralName(core.Choice):
"""
General Name structure for subject/issuer alternative names.
Can represent:
- otherName: Other name forms
- rfc822Name: Email addresses
- dNSName: DNS host names
- x400Address: X.400 addresses
- directoryName: Directory names
- ediPartyName: EDI party names
- uniformResourceIdentifier: URIs
- iPAddress: IP addresses
- registeredID: Registered OIDs
"""
@property
def name(self):
"""Get the chosen name type."""
@property
def chosen(self):
"""Get the chosen name value."""
class GeneralNames(core.SequenceOf):
"""
Sequence of GeneralName values.
Used in subject alternative name and issuer alternative name extensions.
"""
class Extensions(core.SequenceOf):
"""
Sequence of certificate extensions.
Contains all extensions present in a certificate.
"""
class Attributes(core.SetOf):
"""
Set of attributes.
Used in certificate requests and private key info.
"""
class Attribute(core.Sequence):
"""
Single attribute structure.
Structure:
type: OBJECT IDENTIFIER - Attribute type
values: SET OF ANY - Attribute values
"""
@property
def type(self):
"""Get the attribute type OID."""
@property
def values(self):
"""Get the attribute values."""Common X.509 certificate extension structures.
class KeyUsage(core.BitString):
"""
Key Usage extension.
Defines the cryptographic purposes for which the key may be used.
Bit positions:
- digitalSignature (0)
- nonRepudiation (1)
- keyEncipherment (2)
- dataEncipherment (3)
- keyAgreement (4)
- keyCertSign (5)
- cRLSign (6)
- encipherOnly (7)
- decipherOnly (8)
"""
class BasicConstraints(core.Sequence):
"""
Basic Constraints extension.
Structure:
cA: BOOLEAN - Whether this is a CA certificate
pathLenConstraint: INTEGER OPTIONAL - Maximum path length
"""
@property
def ca(self):
"""Check if this is a CA certificate."""
@property
def path_len_constraint(self):
"""Get the path length constraint."""
class ExtKeyUsageSyntax(core.SequenceOf):
"""
Extended Key Usage extension.
Sequence of key usage OIDs defining extended purposes.
"""
class AuthorityKeyIdentifier(core.Sequence):
"""
Authority Key Identifier extension.
Structure:
keyIdentifier: OCTET STRING OPTIONAL - Key identifier
authorityCertIssuer: GeneralNames OPTIONAL - Issuer names
authorityCertSerialNumber: INTEGER OPTIONAL - Serial number
"""
@property
def key_identifier(self):
"""Get the key identifier."""
class SubjectKeyIdentifier(core.OctetString):
"""
Subject Key Identifier extension.
Provides a means of identifying certificates containing a particular public key.
"""from asn1crypto import x509, pem
# Load certificate from PEM file
with open('cert.pem', 'rb') as f:
cert_pem = f.read()
# Convert PEM to DER if needed
if pem.detect(cert_pem):
_, _, cert_der = pem.unarmor(cert_pem)
else:
cert_der = cert_pem
# Parse certificate
cert = x509.Certificate.load(cert_der)
# Access certificate information
print(f"Subject: {cert.subject.human_friendly}")
print(f"Issuer: {cert.issuer.human_friendly}")
print(f"Serial: {cert.serial_number}")
print(f"Valid from: {cert.not_valid_before}")
print(f"Valid until: {cert.not_valid_after}")
print(f"Algorithm: {cert.signature_algorithm}")
# Check extensions
if cert.key_usage_value:
print(f"Key usage: {cert.key_usage_value.native}")
if cert.basic_constraints_value:
constraints = cert.basic_constraints_value
print(f"CA: {constraints.ca}")
if constraints.path_len_constraint is not None:
print(f"Path length: {constraints.path_len_constraint}")from asn1crypto import keys, pem
# Load private key from PEM file
with open('key.pem', 'rb') as f:
key_pem = f.read()
_, _, key_der = pem.unarmor(key_pem)
# Parse private key
private_key = keys.PrivateKeyInfo.load(key_der)
print(f"Algorithm: {private_key.algorithm}")
print(f"Key size: {private_key.bit_size} bits")
# Get corresponding public key
public_key_info = private_key.public_key_info
print(f"Public key fingerprint: {public_key_info.sha256_fingerprint.hex()}")
# For RSA keys, access specific components
if private_key.algorithm == 'rsa':
rsa_key = private_key.private_key.parsed
print(f"Modulus: {rsa_key.modulus}")
print(f"Public exponent: {rsa_key.public_exponent}")from asn1crypto import keys, pem
# Load encrypted private key
with open('encrypted_key.pem', 'rb') as f:
encrypted_pem = f.read()
_, _, encrypted_der = pem.unarmor(encrypted_pem)
# Parse encrypted private key info
encrypted_key = keys.EncryptedPrivateKeyInfo.load(encrypted_der)
print(f"Encryption algorithm: {encrypted_key.encryption_algorithm}")
print(f"Encrypted data length: {len(encrypted_key.encrypted_data)} bytes")
# Note: Actual decryption requires password and is not provided by asn1cryptofrom asn1crypto import x509, core
from datetime import datetime, timezone
# Create a basic certificate name
subject_name = x509.Name([
[{'type': 'common_name', 'value': 'example.com'}],
[{'type': 'organization_name', 'value': 'Example Corp'}],
[{'type': 'country_name', 'value': 'US'}]
])
print(f"Subject: {subject_name.human_friendly}")
# Create general names for SAN extension
san_names = x509.GeneralNames([
x509.GeneralName('dns_name', 'example.com'),
x509.GeneralName('dns_name', 'www.example.com'),
x509.GeneralName('rfc822_name', 'admin@example.com')
])
# Access individual names
for name in san_names:
print(f"{name.name}: {name.chosen}")from asn1crypto import x509
# Assuming we have a parsed certificate
cert = x509.Certificate.load(cert_der)
# Iterate through all extensions
for extension in cert.extensions:
print(f"Extension: {extension['extn_id'].dotted}")
print(f"Critical: {extension['critical']}")
# Handle specific extensions
if extension['extn_id'].dotted == '2.5.29.15': # Key Usage
key_usage = extension['extn_value'].parsed
print(f"Key Usage bits: {key_usage.native}")
elif extension['extn_id'].dotted == '2.5.29.17': # Subject Alt Name
san = extension['extn_value'].parsed
for name in san:
print(f"SAN: {name.name} = {name.chosen}")