9148c358d0
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
6.4 KiB
6.4 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-practical-cryptography | Practical Cryptography | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
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).
매 응용
- TLS 1.3 (transport security).
- Signal Protocol (E2EE messaging — Double Ratchet).
- age/rage (file encryption — replaces GPG).
- JWT/PASETO (stateless tokens — PASETO preferred).
- Password storage (Argon2id with per-user salt).
💻 패턴
AEAD encryption (ChaCha20-Poly1305 with libsodium)
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)
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)
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)
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)
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
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)
# 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 · Security
- 변형: 보안 및 시스템 신뢰성 표준
- 응용: Secret_Management · 보안 및 시스템 신뢰성 표준
- Adjacent: 보안 및 시스템 신뢰성 표준 · 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 |