공개키·대칭키 암호화와 ECDSA·SHA-3/Keccak 운영 설계
대칭키·공개키 암호화, ECDSA 서명, SHA-3·Keccak 해시의 역할과 키 관리, nonce, 상호운용성 운영 원칙을 정리한다.
2026-08-14 · 최초 발행 2025-10-31
암호화·서명·해시는 역할을 분리해서 설계한다
데이터의 기밀성, 무결성, 인증은 하나의 알고리즘으로 해결되지 않는다. 대칭키 암호화는 빠르게 데이터를 보호하고, 공개키 암호화는 키 교환과 인증에 쓰이며, 디지털 서명과 해시는 검증 가능한 무결성의 기반이 된다.
운영 단계에서는 알고리즘 이름보다 키 수명주기, nonce 생성 방식, 패딩 차이로 인한 호환성 문제가 더 직접적인 위험이 되기도 한다.
대칭키 암호화는 데이터 경로를 맡는다
대칭키 암호화는 같은 키로 암호화와 복호화를 수행한다. AES와 GCM·CTR·CBC 같은 운용 모드가 여기에 해당한다. 처리 속도와 오버헤드 측면에서 유리하므로 대용량 데이터 보호에 적합하다.
실무에서는 기밀성과 무결성을 함께 다루기 위해 AEAD 방식인 AES-GCM 또는 ChaCha20-Poly1305를 사용한다.
공개키 암호화는 키 교환과 인증에 적합하다
공개키로 암호화한 데이터를 비밀키로 복호화하는 방식이다. RSA와 ECC(Elliptic Curve Cryptography) 계열이 대표적이다.
키 교환, 서명, 인증에는 적합하지만 대용량 데이터를 직접 암호화하기에는 비효율적이다. 그래서 세션키는 대칭키로 보호하고, 그 키를 교환하거나 인증하는 구간에는 비대칭키를 쓰는 하이브리드 구조를 채택한다.
ECDSA는 메시지 해시를 서명한다
ECDSA(Elliptic Curve Digital Signature Algorithm)는 메시지 해시에 곡선 연산을 적용해 서명과 검증을 수행한다. 비부인성, 무결성, 인증을 제공한다.
안전성은 안전한 곡선 선택, 난수와 nonce(k)의 재사용 방지, 비밀키 보호를 전제로 한다. 특히 ECDSA nonce(k)가 재사용되거나 예측되면 비밀키 유출 위험이 있다.
SHA-3와 Keccak은 이름이 비슷해도 같은 출력이 아니다
해시 함수는 임의 길이 입력을 고정 길이 출력으로 바꾸며 충돌 저항성과 역상 저항성을 제공한다. SHA-3는 Keccak 스펀지 구조를 기반으로 한 NIST 표준이다.
Keccak-256과 SHA3-256은 패딩 차이 때문에 출력이 다르다. Ethereum은 Keccak-256을 사용하므로, 라이브러리와 네트워크가 요구하는 해시 정의를 구분해 호환성을 확인해야 한다.
키 수명주기와 nonce가 운영 경계를 만든다
키는 생성, 보관, 사용, 교체, 폐기에 이르는 전 과정에서 통제해야 한다. HSM/KMS를 이용하고 키 파생과 래핑(envelope encryption) 구조를 적용할 수 있다. 회전 주기, 키 버전 태깅, 감사 가능성, 백업·복구·키 소멸 정책도 함께 관리 대상이다.
대칭 알고리즘에서는 AES-256-GCM을 기본 선택으로 두고, 모바일·CPU 환경에서는 ChaCha20-Poly1305를 대안으로 고려한다. ECDSA에서는 P-256(ES256)의 표준 준수성, secp256k1의 생태계 호환성, 성능과 컴플라이언스의 트레이드오프를 검토한다.
CSPRNG 사용은 필수다. AES-GCM에서는 12바이트 nonce의 유일성을 보장해야 하며, 시스템 전역 nonce 전략이 필요하다. ECDSA에서는 RFC 6979 준수의 결정적 nonce 또는 HSM 내부의 안전한 nonce 생성을 고려할 수 있다.
전송과 저장 데이터에는 AEAD를 우선 적용한다. 서명과 암호화를 함께 쓸 때는 sign-then-encrypt 절차로 메타데이터를 보호한다. API 토큰과 아티팩트는 서명으로 검증하고, 대용량 페이로드에는 해시와 서명을 결합하는 방식이 맞는다.
비대칭 연산은 대칭 연산 대비 10^2~10^4배 오버헤드가 있다. 핫패스에는 대칭키를 두고, 제어면에는 비대칭키를 배치하는 구성이 적합하다. 검증 작업은 배치, 캐시, 오프로딩(HSM/전용 가속기)으로 다룰 수 있으며 최신 정보 확인이 필요하다.
대칭키 암호화, ECDSA, 해시의 처리 흐름
선택 대상별 성능과 운영 특성
| 항목 | 성능 | 확장성 | 일관성 | 안정성 | 운영 편의 |
|---|---|---|---|---|---|
| 대칭(AES-GCM) | 매우 높음 | 매우 높음 | 높음(표준화) | 높음(AEAD) | 높음(키 회전 용이) |
| 서명(ECDSA P-256) | 낮음(단건 지연 상대적 큼) | 중간(배치/오프로딩 필요) | 높음(표준) | 높음(적절 파라미터) | 중간(HSM 의존) |
| 해시(SHA3-256) | 매우 높음 | 매우 높음 | 높음 | 매우 높음 | 높음(운영 단순) |
네트워크부터 공급망까지의 적용 지점
TLS 1.3에서는 ECDHE로 세션키를 합의하고, 인증서 서명에는 ECDSA/RSA를 사용하며, 데이터 평문 보호에는 AES-GCM/ChaCha20-Poly1305를 적용한다. 내부 서비스 간에는 mTLS, 키·인증서 자동 회전, OCSP 스테이플링을 함께 적용할 수 있다.
저장 데이터는 애플리케이션 레벨 AES-GCM으로 암호화하고, 키는 KMS 래핑(envelope)으로 저장한다. 키 버전과 암호화 메타데이터인 키ID, 알고리즘, nonce도 함께 안전하게 보관한다.
API 토큰/JWT에는 ES256(ECDSA P-256) 서명을 적용하고, kid 헤더로 키를 식별하며 키 롤오버를 병행한다. 토큰 검증 실패는 즉시 거부하고 JWK 캐시 TTL을 관리한다.
블록체인·분산원장에서는 ECDSA(secp256k1)를 트랜잭션 서명에 사용하는 사례가 많고, 공개키 해시인 Keccak-256을 주소 유도에 사용한다. SHA3-256과 Keccak-256을 혼동하지 않도록 네트워크별 해시 정의를 재검증해야 한다.
소프트웨어 공급망에서는 컨테이너와 바이너리 서명에 cosign, Sigstore를 사용할 수 있다. 아티팩트 해시(SHA-256/SHA3-256)를 고정하고 CI에서 정책을 검증한다.
Python으로 확인하는 서명·해시·AES-GCM
전제조건
- Python 3.11+
- pip install cryptography, pysha3(Keccak 필요 시)
ECDSA 서명/검증(P-256, SHA3-256)
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.exceptions import InvalidSignature
# 키 생성
private_key = ec.generate_private_key(ec.SECP256R1())
public_key = private_key.public_key()
message = b"hello, cryptography"
# 서명 (SHA3-256)
signature = private_key.sign(message, ec.ECDSA(hashes.SHA3_256()))
# 검증
try:
public_key.verify(signature, message, ec.ECDSA(hashes.SHA3_256()))
print("verify ok")
except InvalidSignature:
print("verify failed")
# PEM 저장(옵션)
pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
print(pem.decode()[:80], "...")
SHA3-256과 Keccak-256 해시
import hashlib
data = b"abc"
sha3 = hashlib.sha3_256(data).hexdigest()
print("SHA3-256:", sha3)
# Keccak-256 (pysha3 필요)
try:
import sha3 # pip install pysha3
k = sha3.keccak_256(data).hexdigest()
print("Keccak-256:", k)
except Exception as e:
print("Keccak-256 unavailable:", e)
AES-256-GCM 대칭 암복호화
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
key = AESGCM.generate_key(bit_length=256) # 32 bytes
aesgcm = AESGCM(key)
nonce = os.urandom(12) # 유일성 보장 필요
aad = b"meta"
ciphertext = aesgcm.encrypt(nonce, b"secret payload", aad)
plaintext = aesgcm.decrypt(nonce, ciphertext, aad)
assert plaintext == b"secret payload"
print("AES-GCM ok, len:", len(ciphertext))
보안 요구와 성능 요구를 함께 다루는 기준
HSM/KMS로 키 추출 불가 정책을 수립하고, 최소 권한 접근 제어와 감사 로깅을 적용한다. 키 회전을 자동화하며 구·신 키를 동시에 검증하는 기간과 키 파기 절차를 표준화한다.
대칭키 암호화에는 AES-256-GCM을 우선하고, 모바일 또는 저가 CPU에서는 ChaCha20-Poly1305를 고려한다. 규제 준수가 필요한 서명에는 P-256을, 생태계 호환성이 중요한 경우에는 secp256k1을 검토하며 결정 근거를 문서화한다.
타이밍 공격을 방지하는 라이브러리와 상수 시간 연산을 사용하고, 패딩 오라클 위험을 피한다. SHA3-256과 Keccak-256의 구분은 상호운용 요구사항과 테스트 케이스에 반영한다. PQC 대비 하이브리드 모드는 NIST PQC 표준 채택 진행 중인 점을 고려해 검토하며 최신 정보 확인이 필요하다.
대칭 암호화 처리량은 수백 MB/sGB/s 수준이며, 비대칭 대비 수백수만 배 고속이다. 이는 환경에 의존하며 최신 정보 확인이 필요하다. HSM 또는 전용 가속기로 검증을 오프로딩하면 인증·서명 TPS를 안정화할 수 있고, 서명 검증 지연은 단건 수백 μs~수 ms 범위로 관리한다.
이 구조는 위·변조 탐지 정확도를 높이고, 키 수명주기 표준화를 통해 운영 리스크를 줄인다. 암호모듈 검증과 데이터 보호 법규 같은 규제 준수에도 도움이 된다.