다음에 올 것을 만들어가는 기술에 대한 심층 기사.

크립토 거래소 보안은 암호학이 아니라 속도에서 무너진다

20분 만에 63억 달러가 빠져나간 바이낸스 해킹이 보여주듯, 거래소 보안은 암호학이 아니라 속도에서 무너집니다. 실제로 빠른 절도를 막는 방법을 정리했습니다.

작은 금고 문에서 빛나는 가치의 흐름이 쏟아져 나오는 동안, 멀리 있는 인물이 너무 늦게 지켜보고 있다.
이번 털이는 금고 문을 부수는 침입이 아니라, 누구도 대응하기 전에 빠르게 빠져나가는 정당하게 승인된 출금입니다.

20분. 공격자들이 바이낸스에서 63억 달러를 빼내는 데 걸린 것으로 알려진 시간입니다. 대부분의 사고 대응 팀이 화상회의에 모이는 데 걸리는 시간보다도 짧죠. 이 사건에서 교훈 하나만 가져간다면 이것이어야 합니다. 크립토 거래소 보안은 수학에서 실패하지 않습니다. 서명은 아마 유효했을 것이고, 키는 원래 하는 일을 정확히 했습니다. 실패는 속도에 있습니다. 탈취된 자격 증명 하나가 사람이 '잠깐'이라고 말하기도 전에 수십억 달러 규모의 되돌릴 수 없는 정산으로 바뀔 수 있다는 것이죠.

초기 보도에 따르면 침투 경로는 탈취된 직원 기기로 보입니다. 거래소는 손실을 전액 보상하고 수사 기관과 협력하겠다고 밝혔습니다. 그래도 안심할 일은 아닙니다. 공격자와 63억 달러 사이에 노트북 한 대만 있다면 그것은 보안 아키텍처가 아니라 언젠가 터질 일화에 불과합니다. 우리는 10년 동안 이 스택에서 엉뚱한 계층을 강화해 왔고, 이번 털이는 그 대가를 치르는 순간입니다.

20분은 설계 실패이지, 운이 나쁜 하루가 아닙니다

이야기에서 가장 숨 가쁜 대목, 즉 '20분!'이라는 부분은 사실 가장 놀랍지 않은 부분입니다. 주요 거래소 털이는 거의 같은 형태를 따릅니다. 몇 달 또는 몇 년에 걸친 조용한 준비 뒤에 몇 분짜리 실행 시간이 옵니다. 2016년 방글라데시 중앙은행 강탈도 똑같았습니다. 공격자들은 은행 네트워크에 몇 달 동안 숨어 있다가 한 번에 허위 SWIFT 메시지를 쏟아냈습니다. 10억 달러를 노렸지만 8,100만 달러만 빼냈고, 그마저도 코레스 은행의 한 날카로운 직원이 이상한 점을 알아채고 나머지를 막았기 때문입니다. 운이 개입했을 뿐, 통제가 작동한 것이 아닙니다.

크립토 거래소를 특별하면서도 취약하게 만드는 것은 전통 금융에서는 거의 함께 나타나지 않는 세 가지 속성의 조합입니다. 정산이 최종적이라 되돌릴 버튼이 없습니다. 정산이 빨라서 검토할 시간도 없습니다. 그리고 정산이 소지자 기반이라 서명 권한을 가진 자가 곧 돈을 가집니다. 전신송금은 코레스 은행에 전화 한 통으로 동결할 수 있지만, 서명된 블록체인 거래 묶음은 서명을 취소할 수 없습니다. 공격자가 거래소의 서명 경로에 들어가면 돈을 훔치는 것이 아니라 순간이동시키는 셈입니다.

그러니 20분이라는 숫자가 스캔들의 핵심은 아닙니다. 진짜 스캔들은 시스템 설계가 20분이면 충분하도록 되어 있다는 점입니다. 아키텍처가 수십억 달러를 점심시간보다 짧은 시간에 건물 밖으로 내보낼 수 있다면, 공격자는 빠를 필요가 없습니다. 빠르게 움직일 수 있도록 설계한 쪽이 바로 여러분입니다.

더 나은 암호학으로도 거래소를 구할 수 없었던 이유

수십억 달러 규모의 털이 소식이 나오면 본능적인 반응은 키 관리가 허술했다는 것입니다. HSM을 썼어야 했다거나, 다자간 연산(MPC)을 썼어야 했다거나, 더 큰 다중서명 정족수가 필요했다는 식이죠. 업계는 이 교훈을 꽤 잘 흡수해서 대부분의 주요 거래소가 실제로 HSM과 MPC를 쓰고 있습니다. 그런데도 털이는 계속됩니다. 전제가 틀렸기 때문입니다. 암호학이 답하는 질문은 하나뿐입니다. 이 요청이 진짜인가? 털이 중에 실제로 중요한 질문, 즉 이 진짜 요청이 일어나야 하는가에는 답할 수 없습니다.

침투 경로가 탈취된 직원 노트북이라면, 즉 유효한 자격 증명, 유효한 MFA 토큰, 출금 오케스트레이션 계층에 대한 유효한 접근 권한을 가진 세션이라면, 시스템이 만들어내는 모든 서명은 암호학적으로 흠잡을 데 없습니다. HSM은 그것을 조작하는 사람이 원격으로 조종당하고 있다는 사실을 알지 못합니다. MPC도 공격자가 참여자 다수의 엔드포인트를 장악하면 도움이 되지 않습니다. 6억 2,500만 달러 규모의 론인 브리지 털이가 바로 그렇게 일어났습니다. 아홉 개 검증인 키 중 다섯 개를 수학을 깨뜨려 얻은 것이 아니라 감염된 기기를 통해 빼앗았습니다. 비트코인 자체가 '해킹'된다는 전설도 자세히 들여다보면 무너지는 경우가 많습니다. 우리도 과대 선전된 PHP 비트코인 익스플로잇을 직접 파헤쳐 봤을 때 암호학이 약점이 아니었다는 것을 확인했습니다. 약점은 언제나 신뢰받는 시스템이 설계된 대로 사용되는 순간이며, 그 시스템을 몰아서는 안 될 누군가가 몰고 있을 때입니다.

암호학은 키를 보호합니다. 하지만 키가 설계된 대로 정확히 사용되는 그 순간을 막아주는 수학은 없습니다.

모니터링으로는 20분짜리 시계를 이길 수 없다

두 번째 본능적 반응은 탐지입니다. 더 나은 모니터링, 이상 탐지, 송금을 지켜보는 AI 같은 것이죠. 거래소에도 이런 장치가 있고 실제로 작동합니다. 그래서 털이가 20분 걸렸다는 것도 알 수 있습니다. 하지만 탐지와 예방은 서로 다른 제품이며 지연 시간 예산도 다릅니다. 성숙한 보안 관제 센터에서도 신뢰도 높은 경보가 울린 뒤 출금을 중단할 권한이 있는 사람에게 도달하기까지 좋은 날에도 수십 분이 걸립니다. 당직자를 호출하고, 오탐이 아닌지 확인하고, 큰 레버를 당길 수 있는 사람에게 올리고, 승인을 받고, 실제로 당기는 과정이죠. 공격자의 전체 작전은 그 루프 안에 여유 있게 들어갑니다.

아무도 가격에 반영하고 싶어 하지 않는 비대칭성입니다. 방어자는 영업시간에 맞춰 인력을 배치하지만, 공격자는 대응 시간이 느려지는 주말과 공휴일을 골라 공격합니다. 그리고 경보가 즉시 울리더라도 경보가 킬 스위치는 아닙니다. 킬 스위치는 사람입니다. 이 장면은 크립토 밖에서도 본 적이 있습니다. 방글라데시 중앙은행 털이는 시스템이 아니라 한 사람이 막았고, 그 사람조차 거의 자리에 없을 뻔했습니다. 마지막 방어선이 '누군가 대시보드를 보고 있겠지'라면 사실 마지막 방어선은 없는 것입니다. 이 논리는 거래소를 넘어서도 적용됩니다. 우리도 자율 에이전트에는 모니터링보다 격리가 낫다는 이유에 대해 비슷한 주장을 한 적이 있습니다. 개입할 능력이 없는 관찰은 실패를 녹화한 기록일 뿐입니다.

밤에 붉은 경보가 깜빡이는 모니터 벽 앞에 놓인 빈 의자.
탐지는 제때 울렸습니다. 문제는 경보와 개입 사이에 일어나야 하는 모든 일입니다.

손실 보전은 해결책이 아니라 자백이다

바이낸스는 모든 손실을 보전하겠다고 밝혔고, 이 회사는 2019년 7,000 BTC 해킹 때도 SAFU 보험기금으로 사용자들의 손실을 메워 준 전례가 있습니다. 당시 시장은 거의 동요하지 않았고, 이번에도 그럴 가능성이 큽니다. 하지만 '보전하겠다'가 아키텍처 관점에서 무엇을 뜻하는지 솔직히 짚어야 합니다. 아무것도 없습니다. 보험은 실패를 흡수하는 재무 장치이지, 실패를 막는 엔지니어링 장치가 아닙니다. 재난을 비용 항목으로 바꿔 줄 뿐이죠. 거래소에게는 합리적이지만, 다음 공격자 앞에는 똑같은 20분짜리 창이 여전히 열려 있습니다.

업계 누구도 공개적으로 말하고 싶어 하지 않는 규모의 문제도 있습니다. 63억 달러 손실은 크립토 산업 전체의 보험 용량을 여러 배 넘어섭니다. 지구상에서 그런 손실을 자체적으로 감당할 수 있는 거래소는 소수에 불과합니다. 그보다 작은 모든 거래소, 즉 의미 있는 고객 자금을 보관하는 수백 곳은 암묵적으로 '우리는 그 대상이 아니겠지'라고 거는 셈입니다. 이것이 바로 은행 업계에서 예금자 보호와 건전성 규제가 메우기 위해 존재하는 공백입니다. '바이낸스는 과실 있는 보안 관리로 기소되어야 하지 않나?'라는 다소 거친 본능도 실제 문제를 가리키고 있습니다. 한 세기 전에 우리는 남의 돈을 맡은 기관이 스스로 위험 선호도를 정할 수 없다고 결정했습니다. 크립토는 15년 동안 털이 사건을 하나씩 겪으며 그 결정을 다시 따지고 있습니다.

서킷 브레이커: 시장이 이미 발명한 해법

답답한 부분은 금융이 이 문제를 수십 년 전에 다른 방향으로 이미 풀었다는 점입니다. 1987년 주가 폭락 이후 주식 거래소들은 가격이 너무 빠르고 크게 움직이면 거래를 중단하는 서킷 브레이커를 도입했습니다. 중단이 사기나 폭락을 없앤다고 주장하는 사람은 없습니다. 핵심은 통제되지 않는 과정을 감독 가능한 과정으로 바꿔 인간의 판단을 위한 시간을 버는 것입니다. 같은 논리가 출금에도 적용되며, 놀랄 만큼 단순합니다. 서명이 아무리 유효하더라도 어떤 거래소도 짧은 시간 안에 자산의 작은 비율 이상을 내보낼 수 없어야 합니다.

출금 서킷 브레이커는 서명 경로에 자리 잡고 속도 자체를 이상 징후로 취급하는 정책 엔진입니다. 중요한 점은 요청이 진짜인지 묻지 않는다는 것입니다. 모든 요청이 진짜이면서 동시에 악의적일 수 있다고 가정하고, 그래도 피해 반경을 제한합니다.

from dataclasses import dataclass
from datetime import datetime, timedelta
@dataclass
class WithdrawalPolicy:
window: timedelta = timedelta(minutes=30)
max_outflow_pct: float = 2.0      # of hot-wallet balance per window
hard_freeze_pct: float = 5.0      # trip the breaker entirely
large_threshold_usd: float = 1_000_000
large_delay: timedelta = timedelta(hours=24)
class CircuitBreaker:
def __init__(self, policy: WithdrawalPolicy):
self.policy = policy
self.recent: list[tuple[datetime, float]] = []
self.tripped = False
def authorize(self, amount_usd: float, hot_balance_usd: float) -> str:
if self.tripped:
return "REJECT: breaker tripped, manual review required"
now = datetime.utcnow()
cutoff = now - self.policy.window
self.recent = [(t, a) for t, a in self.recent if t > cutoff]
outflow_pct = 100 * (sum(a for _, a in self.recent) + amount_usd) / hot_balance_usd
if outflow_pct > self.policy.hard_freeze_pct:
self.tripped = True
return "HALT: outflow exceeded safety threshold, withdrawals frozen"
if outflow_pct > self.policy.max_outflow_pct:
return "QUEUE: velocity limit reached, withdrawal delayed"
if amount_usd > self.policy.large_threshold_usd:
return f"DELAY: held {self.policy.large_delay} for review"
self.recent.append((now, amount_usd))
return "APPROVE"

이번 털이의 숫자로 이것이 무엇을 가져오는지 보십시오. 핫월렛에 63억 달러의 10%만 있다고 해도, 핫 잔액의 5%를 넘으면 하드 동결하는 장치는 자동 손실을 약 3,100만 달러 선에서 막습니다. 나쁜 오후 하루이지, 존재를 위협하는 사건은 아닙니다. 더 중요한 것은 공격자의 20분짜리 질주가 며칠짜리 느린 행군이 된다는 점입니다. 그래야 모니터링 팀이 비로소 제 역할을 할 수 있습니다. 핵심은 공격자를 이기는 것이 아니라 사람이 도착할 때까지 시간을 늘리는 것입니다. 이것이 고전적 의미의 방어적 엔지니어링입니다. 최악의 실패가 지루하게 느껴지도록 시스템을 설계하는 것이죠.

거대한 산업용 차단기 스위치가 내려가고, 뒤편의 빛나는 전선 다발이 어두워지는 모습.
속도 서킷 브레이커는 도둑질을 멈추지는 않습니다. 사람이 멈출 수 있을 만큼 도둑질을 느리게 만듭니다.

출금 지연과 지루한 은행업의 가치

서킷 브레이커는 속도를, 지연은 규모를 다룹니다. 전통 금융 시스템의 비밀 무기는 정교함이 아니라 마찰입니다. 전신송금은 회수할 수 있고, ACH는 며칠이 걸립니다. 큰 이동에는 보류 기간을 두고, 별도 채널을 통해 알려진 연락처로 확인 전화를 겁니다. 크립토는 즉시 최종 정산이 상품이었기 때문에 이 모든 것을 걷어냈습니다. 하지만 사용자가 실제로 신경 쓰는 거래 경험은 건드리지 않고, 출금 경계에서 마찰을 선별적으로 되살릴 수 있습니다.

  • 시간 잠금이 걸린 대액 출금. 기준을 넘는 금액은 눈에 보이는 대기열에서 24시간을 기다립니다. 사용자는 이를 감안해 계획할 수 있지만 공격자는 그럴 수 없습니다. 지연되는 매 시간이 침해를 발견할 시간이 되기 때문입니다.
  • 핫월렛 하드 상한. 정상적인 출금 24시간분에 필요한 만큼만 온라인에 둡니다. 대부분의 거래소에서는 자산의 한 자릿수 초반 비율입니다. 콜드 스토리지 이동에는 여러 당사자가 참여하고 며칠이 걸리는 절차가 필요하며, 어떤 자격 증명으로도 가속할 수 없습니다.
  • 지연 적용 변경이 있는 주소 화이트리스트. 새 출금 주소는 대역 외 확인을 거친 뒤 지연 후에 활성화됩니다. 침입 중에 목적지 주소를 바꿔치기하는 고전적 수법을 막아 줍니다.
  • 분할된 서명 권한. 어떤 단일 엔드포인트, 역할, 세션도, 인증되었더라도 정해진 금액 이상은 옮길 수 없어야 합니다. 피해 반경이 작으면 침입 경로가 덜 중요해집니다. LiteLLM 공급망 사고가 파이썬 생태계에 개발자 기기가 가장 약한 표적이라는 교훈을 준 것도 같은 맥락입니다.
  • 부채를 포함한 공개 준비금 증명. 도난 방지 장치는 아니지만, 은폐 옵션을 일찍 치워 버리는 지급능력 경보 장치입니다.

이 방법들이 요구하지 않는 것을 보십시오. 새로운 암호학, 새로운 하드웨어, 새로운 과학이 필요 없습니다. 모두 정책입니다. 또한 인기도 없습니다. 마찰, 지연, 한도는 모두 제품 관리자의 악몽이고, 거래소의 경제성은 처리량과 모든 것의 즉시성에 보상을 주기 때문입니다. 긴장은 실재하며, 지금까지 업계의 답은 화려한 UX를 위해 치명적인 꼬리 위험을 감수하는 것이었습니다. 63억 달러, 20분짜리 털이는 그 거래의 대가가 돌아온 모습입니다.

속도는 선택이니, 의도적으로 선택하라

사고 대응에는 이런 말이 있습니다. 초 단위가 중요할 때 우리는 며칠에서 몇 주에 걸쳐 패치한다. 이번 털이는 그 말을 뒤집습니다. 초 단위가 중요할 때 돈은 몇 분 만에 움직이고, 방어자의 전체 절차는 더 느린 세상을 위해 만들어져 있었습니다. 더 똑똑한 경보나 더 강한 키로는 이 문제를 고칠 수 없습니다. 공격자는 키를 깨뜨리는 것도, 경보를 피하는 것도 아니기 때문입니다. 그들은 여러분의 시스템을 설계된 대로, 여러분이 설계한 속도로 사용하고 있을 뿐입니다.

그래서 모든 거래소 엔지니어에게, 솔직히 말해 가치를 옮기는 시스템을 만드는 모든 엔지니어에게 던질 정직한 질문은 '공격자를 영원히 막으려면 어떻게 해야 하나?'가 아닙니다. 그건 불가능합니다. 노트북은 감염되고, 사람은 피싱을 당하고, 공급망은 오염됩니다. 질문은 이것입니다. 누군가 들어왔을 때 여러분의 아키텍처는 빠르게 실패하는가, 천천히 실패하는가? 지금 업계의 답은 빠르고, 최종적이며, 생중계되는 실패입니다. 속도 상한, 시간 잠금 출금, 핫월렛 하드 한도가 그 답을 바꾸는 방법입니다. 기술은 사소합니다. 약간의 마찰을 받아들이려는 의지가 어려울 뿐입니다. 업계가 스스로 그 마찰을 선택하지 않는다면, 커피 리필 사이에 63억 달러가 날아가는 것을 지켜본 규제 당국이 결국 대신 선택하게 될 것입니다.