수출용 암호: 2015년에 TLS를 깬 1990년대 법

1990년대 미국 정부는 기업들이 일부러 깨지는 암호를 해외에 팔게 만들었다. 그 약한 암호는 법보다 15년을 더 살아남았고 — 2015년, FREAK과 Logjam이 그것을 웹의 3분의 1에서 다시 켰다.

2015년 3월, 한 연구팀이 당신의 브라우저와 은행 사이에 끼어들어, 연결을 100달러쯤이면 깰 수 있을 만큼 약한 암호로 끌어내리고, 전부 읽어낼 수 있음을 보였다. 그들이 파고든 약점은 새 버그가 아니었다. 1992년의 정책 결정이었고, 다들 새 천 년 무렵에 꺼진 줄 알았던 것이었다. 꺼지지 않았다. 그저 코드 안에 잠든 채 15년을 앉아서, 누군가 다시 켜주기를 기다리고 있었을 뿐이다.

이건 수출용 암호(export-grade cryptography) 이야기다 — “좋은 편”을 위해 정부가 일부러 약화시킨 암호 모드를 강제하면 무슨 일이 벌어지는지에 대해, 우리가 가진 가장 통제된 실험에 가까운 사례다. 실험은 20년을 돌았다. 결과는 분명하고, 그 아이디어가 돌아올 때마다 — 대략 회기(會期)마다 한 번씩 돌아온다 — 기억해 둘 값어치가 있다.

백도어를 실어 나른 법

1996년까지 미국은 강한 암호를 군수품으로 분류했다 — 전투기·유도미사일과 같은 수출 범주, 국무부의 무기 통제 체제 아래였다. 집에서는 좋은 암호를 써도, 해외로 보내려면 받을 수 없는 무기 수출 허가가 필요했다. 업계가 맺은 현실적 타협은 추하고 구체적이었다: 국제 판매용 소프트웨어는 자기 암호를 스스로 불구로 만들어야 했다. RSA 키 교환은 512비트로 상한이 걸렸다. 대칭 암호는 40비트로 걸렸다. 넷스케이프는 아예 두 개의 빌드를 냈다 — “미국판”과 “국제판” — 그리고 국제판은 설계상 깨지게 되어 있었다.

정확히 누구에게 깨지도록? 그게 요점이었다. 40비트 키나 512비트 RSA 모듈러스는 1995년의 취미가가 깰 수 있는 선을 넘었지만, 하드웨어로 가득 찬 방을 가진 정보기관에는 넉넉히 손 닿는 거리였다. 수출용 암호는 가독성 보증이었다: 외국 트래픽은 규칙을 쓴 사람들에게 계속 읽히게 둔다. 있는 그대로 부르자 — 프로토콜 자체에 협상되어 박힌, 합법적 접근(lawful-access) 백도어였다. SSL 3.0과 TLS 1.0은 그 지문을 지금까지도 사이퍼 목록에 담고 있다: 이름에 EXPORT가 붙은 것들, RSA_EXPORTDHE_EXPORT, 일부러 허약하게 만든 것들.

암호 전쟁은 대체로 소프트웨어 업계의 승리로 끝났다. 대니얼 번스타인은 정부를 상대로, 소스 코드는 수정헌법 1조가 보호하는 표현이라 주장하며 소송했고, Bernstein v. United States를 다룬 제9순회항소법원의 판단은 수출 체제의 법적 발판을 무너뜨리는 데 일조했다. 암호는 1996년 국무부 군수품 목록에서 상무부 통제로 옮겨졌고, 2000년에는 대량 판매·오픈소스 소프트웨어가 진짜 암호를 실을 수 있을 만큼 규칙이 완화됐다. 전쟁은 이겼다. 다들 집으로 돌아갔다.

그리고 아무도 코드를 지우지 않았다.

죽은 암호는 사라진 암호가 아니다

해결된 정책 싸움을 15년 뒤의 보안 참사로 바꾸는 대목이 여기다: 수출용 사이퍼는 구현에서 한 번도 뜯겨 나가지 않았다. 왜 그러겠나? 여전히 작동했으니까. 어딘가의 낡은 클라이언트가 아직 그걸 요청할지도 모르니까. 코드를 지우는 건 무섭고 티도 안 나는 일이고, “이제 아무도 협상 안 하는 사이퍼 하나를 더 지원한다”는 취약점처럼 느껴지지 않는다. 하위 호환처럼 느껴진다.

그래서 OpenSSL은 수출용 사이퍼를 남겼다. 애플의 SecureTransport도 남겼다. 마이크로소프트의 SChannel도 남겼다. 서버들은 계속 그걸 광고했다. 1990년대 규제를 만족시키려 만든 기능이, 꺼진 채 그러나 부재하진 않은 상태로 세계의 TLS 스택에 조용히 얹혀 2010년대까지 실려 왔다 — 벽에 아직 박힌, 잠기지 않고 페인트만 덧칠된 폐쇄된 문의 소프트웨어판이었다. 2015년 두 연구팀이 걸어가 그 문을 밀었다.

FREAK: 정부가 당신 대신 크기를 정해 준 키를 인수분해하다

첫 번째 밀기는 FREAK — Factoring RSA Export Keys, CVE-2015-0204, 2015년 3월 3일 INRIA와 마이크로소프트 리서치의 miTLS 그룹이 공개했다. 시작은 TLS 상태 기계(state machine) 버그 계열의 하나였다: 알고 보니 상당수의 클라이언트가, 자기가 요청한 적도 없는 메시지를 받아들였다. 구체적으로, 서버가 약한 512비트 수출용 RSA 키를 담은 ServerKeyExchange를 보내면, 취약한 클라이언트는 그걸 덥석 받았다 — 클라이언트는 강한 보통 RSA만 제안했고, 그 메시지가 핸드셰이크에 존재할 정당한 이유가 없는데도.

그 버그가 지렛대다. 공격은 이렇게 흐른다. 당신은 연결 중간에 들어간다. 클라이언트가 강한 RSA를 청하는 ClientHello를 보내면, 당신은 그걸 RSA_EXPORT를 요청하도록 고쳐 쓴다. 서버는 — 아직 수출용 사이퍼를 지원한다면, 그리고 3분의 1이 그랬다 — 기꺼이 응해 512비트 임시 RSA 키에 서명한다. 버그 있는 클라이언트는 그 약한 키를 아무 일 없다는 듯 받아들인다. 이제 당신과 평문 사이엔 512비트 RSA 모듈러스가 서 있고, 512비트 RSA는 아주 오래전부터 안전하지 않았다.

얼마나 안전하지 않냐고? 연구진은 아마존 EC2에서 약 7.5시간, 약 104달러의 연산으로 하나를 인수분해했다. 다른 추정치는 12시간 이내, 약 50달러로 잡았다. 그리고 잔혹한 곱셈기가 있었다: 많은 서버가 프로세스 시작 때 수출용 키를 딱 하나 만들어, 재시작 전까지 모든 연결에 재사용했다. 한 번 인수분해하면 — 한나절, 100달러 — 그 서버가 살아 있는 내내 그 서버를 사칭하거나 수출용 세션을 복호화할 수 있다. 약 1,400만 HTTPS 사이트를 훑은 스캔에서, 브라우저가 신뢰하는 서버의 약 36%가 이 공격을 가능케 하는 수출용 RSA 사이퍼를 여전히 지원하고 있었다. 무명 서버가 아니다. 신뢰받는 웹의 3분의 1이, 클린턴 행정부 시절에 발주된 약점을 지고 있었다.

Logjam: 같은 발상, 그러나 중요한 곳에서 더 나쁜

두 달 반 뒤인 2015년 5월, Logjam(CVE-2015-4000)이 왔다. INRIA, 마이크로소프트 리서치, 존스홉킨스, 미시간, 펜실베이니아를 아우르는 더 큰 팀이었다. Logjam은 FREAK이 RSA에 한 일을 디피-헬만에 했다 — 512비트 DHE_EXPORT 사이퍼로의 중간자 다운그레이드 — 겉으로는 같은 이야기다. 하지만 그 밑의 메커니즘이 더 섬뜩하고, 바로 그 부분이 새겨둘 값어치가 있다.

디피-헬만을 깬다는 건 주어진 소수(prime)에 대해 이산로그 문제를 푸는 것이다. 알려진 최선의 방법인 수체 체(number field sieve)에는, 어느 편에 서 있느냐에 따라 우아하거나 끔찍한 성질이 있다: 작업의 압도적 대부분이 소수 그 자체에만 달려 있고, 특정 키 교환에는 달려 있지 않다. 한 소수에 대해 거대한 사전 계산을 한 번 해 두면, 그 뒤로는 그 소수를 쓰는 개별 연결을 빠르게 깰 수 있다. 비용은 앞에 몰려 있고, 그 소수를 공유하는 모든 세션에 걸쳐 분할 상환된다.

이제 디피-헬만 파라미터가 실제로 어떻게 배포됐는지 떠올려 보라. 아무도 자기 소수를 직접 만들지 않는다. 까다롭고 틀리기 쉬우니, 구현이 기본값을 실어 준다. 512비트 수출용 DH의 경우, 손에 꼽을 몇 개의 하드코딩된 소수 — 아파치에, mod_ssl에 구워 넣은 — 가 거의 전부를 덮었다. Logjam 팀은 가장 흔한 512비트 소수 하나에 대한 단 한 번의 사전 계산으로 DHE_EXPORT를 지원하는 서버의 80%를 공격할 수 있음을 발견했다. 소수 하나, 한 번 깨서, 취약한 인터넷의 압도적 다수를 열었다. 상위 100만 HTTPS 사이트의 약 8.4%가 노출돼 있었다.

그리고 연구진은, 모두가 실제 디피-헬만에 쓰던 크기로 계산해 봤다: 1024비트. 1024비트 사전 계산은 엄청나게 더 비싸다 — 학계 예산 너머, 특수 목적 하드웨어를 1년 넘게 짓는 국가 규모의 영역이다. 하지만 불가능하진 않고, 여기 결정타가 있다: 512비트 경우와 똑같이, 인터넷의 대부분이 극소수의 흔한 1024비트 소수에 기대고 있었다. 그중 하나에 대해 한 번 사전 계산하면, 그 소수를 쓰는 세계 HTTPS·VPN·SSH 트래픽의 상당 부분을 수동적으로 복호화할 수 있다 — 연결마다 침입할 것 없이, 그저 조용히 읽는 것이다. 대규모 VPN 복호화를 묘사한 유출된 정보기관 문서들이, 갑자기 들어맞는 메커니즘을 갖게 됐다. 증명은 아니었다. 보고된 능력과 너무 잘 맞아떨어져서, “그들이 어떻게 했는지 우리는 모른다”는 말이 더는 정직한 말이 아니게 된, 그런 청사진이었다.

이 실험이 실제로 증명한 것

두 공격을 나란히 놓으면, 교훈은 “512비트 암호는 약하다”가 아니다. 그건 1998년에도 다들 알았다. 교훈은 일부러 약화시킨 모드가 시간이 지나며 어떻게 되는가에 관한 것이고, 두 부분으로 온다.

첫째: 한 적을 위해 만든 약점은, 결국 모든 적을 위한 약점이다. 수출용 사이퍼는 특정하고, 강력하며, 합법으로 추정되는 행위자가 특정 트래픽을 읽을 수 있도록 설계됐다. 그 힘을 한쪽에는 주고 다른 모두에게선 거두는 암호학적 구성은 존재하지 않는다 — 512비트 키는 공격자의 신분증을 검사하지 않는다. 일단 약한 모드가 배포된 소프트웨어에 존재하면, 그것과 클라우드 계정을 가진 대학원생 사이에 남은 유일한 것은 하드웨어 비용이고, 하드웨어 비용은 한 방향으로만 간다. “NSA만 이걸 깰 수 있다”와 “100달러 가진 누구나 이걸 깰 수 있다” 사이의 간격은 약 20년이었다 — 다시 말해, 한 사람의 경력만큼이었다.

둘째: 쓰지 않는다고 기능이 꺼지지는 않는다. 수출용 사이퍼는 2000년 무렵 건강한 클라이언트가 협상을 멈췄다는 의미에서 “은퇴”했다. 정작 중요한 의미에서는 은퇴하지 않았다 — 코드에서 제거되고, 서버가 거부하고, 불가능해진다는 의미에서는. 15년의 휴면은 누군가 상태 기계 버그와 ClientHello를 고쳐 쓸 의지를 찾은 순간 끝났다. 아직 닿을 수 있는 죽은 코드는 죽은 게 아니다. 안전장치에 페인트만 칠한, 장전된 약점이다.

그래서 “책임 있는” 혹은 “합법적 접근” 암호를 향한 되풀이되는 제안들 — 여기 키 위탁 하나, 저기 강제된 약한 모드 하나, 늘 좋은 편만 키를 쥔다는 보증과 함께 — 은 FREAK과 Logjam을 출력해 탁자 위로 밀어주는 대접을 받아 마땅하다. 우리는 이미 이 실험을 돌렸다. 좋은 편을 위해 약화된 모드를, 실제 프로토콜 안에, 20년 동안 강제했다. 그것은 좋은 편에만 머물지 않았고, 제 시대에 머물지 않았으며, 치우는 데는 지구상 모든 주요 TLS 구현에 걸친 수년의 협업이 들었다 — 그리고 그 일은, 크게 보면 아직도 다 끝나지 않았다. 옛 사이퍼가 여전히 컴파일되어 들어간 스택이 늘 하나 더 있기 때문이다.

1990년대는 암호에 관한 결정을 내릴 수 있었고, 그 값은 2010년대가 치러야 했다. 그게 당신에게 남아야 할 부분이다. 백도어를 강제하는 사람들과 결국 그 문으로 걸어 들어가는 사람들은 거의 언제나 같은 사람이 아니고, 두 번째 무리는 첫 번째 무리의 허락이 필요 없다.

토론 참여

← 블로그로 돌아가기