Files
secpaste/secpaste/crypto/aes.py
nanoclaw eb56ed4aa2 Restructure package for proper Python import
Move source files into nested secpaste/ directory to fix module imports.
This allows the package to be properly installed with pip and imported as
'import secpaste' or 'python -m secpaste.cli'.

Changes:
- Move all Python files into secpaste/secpaste/ structure
- Add .gitignore for Python artifacts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-07 23:18:15 +00:00

66 lines
1.9 KiB
Python

"""AES-256-GCM cipher backend."""
import os
import base64
from typing import Tuple
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from .base import CipherBackend
class AESGCMCipher(CipherBackend):
"""AES-256-GCM authenticated encryption."""
def encrypt(self, plaintext: bytes) -> Tuple[bytes, str]:
"""
Encrypt using AES-256-GCM.
Returns:
Tuple of (nonce + ciphertext, base64url-encoded key)
"""
# Generate random 256-bit key
key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)
# Generate random 96-bit nonce (recommended for GCM)
nonce = os.urandom(12)
# Encrypt and authenticate
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
# Prepend nonce to ciphertext for storage
encrypted_data = nonce + ciphertext
# Encode key for URL fragment
key_encoded = base64.urlsafe_b64encode(key).decode('ascii').rstrip('=')
return encrypted_data, key_encoded
def decrypt(self, ciphertext: bytes, key: str) -> bytes:
"""
Decrypt using AES-256-GCM.
Args:
ciphertext: Nonce (12 bytes) + encrypted data
key: Base64url-encoded 256-bit key
"""
# Decode key (add padding if needed)
padding = '=' * (4 - len(key) % 4) if len(key) % 4 else ''
key_bytes = base64.urlsafe_b64decode(key + padding)
if len(key_bytes) != 32:
raise ValueError("Invalid key length. Expected 32 bytes for AES-256.")
# Extract nonce and ciphertext
nonce = ciphertext[:12]
encrypted = ciphertext[12:]
# Decrypt
aesgcm = AESGCM(key_bytes)
plaintext = aesgcm.decrypt(nonce, encrypted, None)
return plaintext
def get_name(self) -> str:
"""Return cipher name."""
return "aes-256-gcm"