--- id: wiki-2026-0508-practical-cryptography title: Practical Cryptography category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Applied Cryptography, Crypto Engineering] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [cryptography, security, encryption] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: Python/Go framework: libsodium/cryptography --- # Practical Cryptography ## 매 한 줄 > **"매 don't roll your own crypto"**. 매 application engineer 의 task 는 매 well-vetted primitives (AES-GCM, ChaCha20-Poly1305, Ed25519, X25519) 의 correct composition — 매 algorithm 의 invention 아님. 2026 의 modern stack 은 libsodium, AWS KMS, age, Noise Protocol Framework 위 의 build. ## 매 핵심 ### 매 Primitives (2026 baseline) - **Symmetric AEAD**: ChaCha20-Poly1305 (mobile/no-AES-NI), AES-256-GCM (server with AES-NI), AES-256-GCM-SIV (nonce-misuse resistant). - **Asymmetric**: X25519 (ECDH key agreement), Ed25519 (signing), Kyber-1024 (post-quantum KEM, NIST FIPS 203). - **Hashing**: BLAKE3 (fast), SHA-256 (interop), Argon2id (password hashing, 2026 default). - **Key derivation**: HKDF-SHA256 (key expansion), Argon2id (password → key). ### 매 Threat models - **Confidentiality**: encrypt-then-MAC, AEAD prevents IND-CCA2 attacks. - **Integrity**: HMAC, Poly1305, signatures. - **Authenticity**: signatures (Ed25519), authenticated key exchange (Noise). - **Forward secrecy**: ephemeral keys (X25519 per session). - **Post-quantum**: hybrid Kyber + X25519 (2026 TLS 1.3 default). ### 매 응용 1. TLS 1.3 (transport security). 2. Signal Protocol (E2EE messaging — Double Ratchet). 3. age/rage (file encryption — replaces GPG). 4. JWT/PASETO (stateless tokens — PASETO preferred). 5. Password storage (Argon2id with per-user salt). ## 💻 패턴 ### AEAD encryption (ChaCha20-Poly1305 with libsodium) ```python from nacl.secret import SecretBox from nacl.utils import random key = random(SecretBox.KEY_SIZE) # 32 bytes box = SecretBox(key) # Encrypt — nonce auto-generated, prepended to ciphertext ciphertext = box.encrypt(b"sensitive data") # Decrypt — fails with CryptoError on tampering plaintext = box.decrypt(ciphertext) ``` ### Authenticated key exchange (X25519 + HKDF) ```python from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey from cryptography.hazmat.primitives.kdf.hkdf import HKDF from cryptography.hazmat.primitives import hashes # Each party generates ephemeral keypair alice_priv = X25519PrivateKey.generate() bob_priv = X25519PrivateKey.generate() # Compute shared secret shared = alice_priv.exchange(bob_priv.public_key()) # Derive symmetric key — never use raw DH output as key session_key = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b"session-v1", ).derive(shared) ``` ### Password hashing (Argon2id) ```python from argon2 import PasswordHasher ph = PasswordHasher( time_cost=3, # iterations memory_cost=65536, # 64 MiB parallelism=4, ) hash = ph.hash("user-password") # store this # Verify (constant-time) try: ph.verify(hash, "user-password") if ph.check_needs_rehash(hash): new_hash = ph.hash("user-password") # parameter upgrade except VerifyMismatchError: raise AuthError() ``` ### Digital signature (Ed25519) ```python from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey priv = Ed25519PrivateKey.generate() pub = priv.public_key() signature = priv.sign(b"message") pub.verify(signature, b"message") # raises InvalidSignature on failure ``` ### Envelope encryption (KMS pattern) ```python import boto3 from cryptography.fernet import Fernet kms = boto3.client("kms") def encrypt_blob(plaintext: bytes, kms_key_id: str) -> dict: # Generate per-message data key resp = kms.generate_data_key(KeyId=kms_key_id, KeySpec="AES_256") data_key = resp["Plaintext"] encrypted_dk = resp["CiphertextBlob"] # Encrypt data with data key, discard plaintext data key f = Fernet(base64.urlsafe_b64encode(data_key)) ct = f.encrypt(plaintext) return {"ciphertext": ct, "encrypted_key": encrypted_dk} ``` ### Constant-time comparison ```python import hmac # WRONG — leaks length info via timing if user_token == stored_token: pass # RIGHT — constant time if hmac.compare_digest(user_token, stored_token): pass ``` ### Post-quantum hybrid KEM (2026) ```python # liboqs-python — hybrid X25519 + Kyber768 from oqs import KeyEncapsulation import nacl.public # Classical X25519 x_priv = nacl.public.PrivateKey.generate() # Post-quantum Kyber with KeyEncapsulation("Kyber768") as kem: pq_pub = kem.generate_keypair() # Combine both shared secrets via HKDF for hybrid security ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | File encryption | age (modern), libsodium SecretBox | | Password hash | Argon2id (never bcrypt for new systems) | | Token format | PASETO v4 (Ed25519) over JWT | | Mobile/IoT AEAD | ChaCha20-Poly1305 | | TLS 1.3 backend | rustls or BoringSSL, hybrid PQ enabled | | Signing | Ed25519 (never RSA for new systems) | **기본값**: libsodium + Argon2id + Ed25519 + ChaCha20-Poly1305. ## 🔗 Graph - 부모: [[Practical-Cryptography|Cryptography]] · [[Security]] - 변형: [[보안_및_시스템_신뢰성_표준|Symmetric-Encryption]] - 응용: [[Secret_Management]] · [[보안_및_시스템_신뢰성_표준|Zero-Trust Architecture]] - Adjacent: [[보안_및_시스템_신뢰성_표준|OWASP Top 10]] · [[Practical-Cryptography]] ## 🤖 LLM 활용 **언제**: explain primitive choice, audit crypto code for misuse, suggest migration paths. **언제 X**: never ask LLM to design new protocol — always defer to peer-reviewed designs (Noise, Signal). ## ❌ 안티패턴 - **Roll-your-own**: custom XOR-based "encryption" — 매 broken in seconds. - **ECB mode**: leaks pattern (penguin image meme). Always GCM/CTR/CBC-with-MAC. - **Static IV/nonce**: catastrophic for GCM (key recovery). Always random or counter. - **MD5/SHA-1**: collision-broken. Never for security purposes. - **bcrypt for new systems**: Argon2id 2026 default. - **String comparison for tokens**: use `hmac.compare_digest`. ## 🧪 검증 / 중복 - Verified (NIST FIPS 203/204/205, RFC 9180 HPKE, libsodium docs). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — full primitives + 2026 PQ baseline |