시스템이 연산을 수행하는 데 걸리는 시간의 차이를 분석하여 암호화 정보를 알아내는 해킹 기법.
어떻게 가능한가?
많은 프로그래밍 언어들은 문자열 비교 시 처리 속도를 높이기 위해 ‘단락 평가’를 사용한다. 비교 중에 일치하지 않는 문자가 하나라도 발생하면, 남은 연산을 진행하지 않고 바로 실패를 반환하는 방식이다. (다중 논리 연산을 생각하면 쉽다.)
즉 일치하는 문자가 많아질 수록 연산 속도가 길어지게 되는데, 이것을 악용하는 것이다.
방지법
어렵지 않다. 단락 평가를 사용하지 않고 ‘정수 시간 비교’ 방식을 사용하면 간단히 해결된다. 말이 어렵지만 그냥 틀린 문자가 있어도 계속 연산하면 된다.
기본적인 방식
⚠️ JavaScript 관련 안내
알고리즘 참고용이다. JavaScript 엔진의 경우 실행 최적화(JIT Compilation)하는 과정에서 반복문을 임의로 풀어버리거나(Loop unrolling), 예상치 못한 방식으로 실행 파이프라인을 재정렬할 수 있다.
하단에 Node.js 기본 Crypto 모듈을 사용하는 것을 권장한다.
function constantTimeCompare(a, b) { // 1. 두 문자열의 길이가 다르면 이 차이값을 누적 변수 초기값으로 설정합니다. // 길이가 일치한다면 result는 0으로 시작합니다. let result = a.length ^ b.length; // 2. 두 문자열 중 더 긴 문자열의 길이를 기준으로 반복문을 실행합니다. const len = Math.max(a.length, b.length); // 3. 중간에 불일치가 발생해도 절대 return하지 않고 끝까지 반복합니다. for (let i = 0; i < len; i++) { // 인덱스가 문자열 길이를 초과하면 0(더미 값)을 사용합니다. const charA = i < a.length ? a.charCodeAt(i) : 0; const charB = i < b.length ? b.charCodeAt(i) : 0; // XOR(^) 결과가 0이면 두 문자가 같음을 의미하고, 이를 OR(|)로 계속 누적시킵니다. result |= (charA ^ charB); } // 4. 모든 문자가 일치하고 길이도 동일했다면 result는 최종적으로 0이 됩니다. return result === 0;}
// 사용 예제const isMatch = constantTimeCompare("mySecretToken123", "mySecretToken123");console.log(isMatch); // true
Node.js 기본 Crypto 모듈 활용
Node.js 에서는 2016년 Node 버전 6부터 타이밍 공격 방지를 위한 함수를 제공해주고 있다.
const crypto = require('crypto');
// 비교할 두 값을 Buffer 객체로 준비합니다.const userInput = Buffer.from('user-provided-secret');const storedSecret = Buffer.from('user-provided-secret');
// 길이가 다르면 timingSafeEqual 실행 시 에러가 발생하므로 길이를 먼저 확인합니다.if (userInput.length !== storedSecret.length) { console.log('인증 실패: 길이가 다릅니다.');} else { // 상수 시간 알고리즘을 통해 안전하게 값을 비교합니다. const isMatch = crypto.timingSafeEqual(userInput, storedSecret); console.log('인증 성공 여부:', isMatch); // 일치할 경우 true 반환}
지금도 의미가 있나?
연산 속도가 빨라지고 대부분의 지연이 네트워크에서 발생하기 때문에 불가능할 것이라 생각하기 쉽지만, 오히려 새로운 프로토콜의 특성을 이용한 실증 사례들이 나오고 있다.
Timeless Timing Attack
2020년 보안 학회에서 발표된 기법이다. HTTP/2의 멀티플렉싱(Multiplexing) 기능을 악용하여, 공격용 요청과 대조군 요청을 단일 네트워크 패킷에 담아 서버로 전송한다.
이 요청들은 서버에 정확히 동시에 도착하여 병렬로 처리되기에, 공격자는 전체 왕복 시간(RTT)을 측정할 필요 없이 어떤 요청의 응답이 먼저 네트워크를 타고 돌아오는지(순서)만 비교하면 된다. 이 방식을 사용하면 네트워크 지연(Jitter)의 영향을 완벽히 배제할 수 있어 인터넷 너머의 원격 서버를 상대로도 100나노초(ns) 수준의 차이를 구별해 낼 수 있다.
TCP 타임스탬프 악용
2026년 NDSS에 발표된 연구다. 네트워크 왕복 시간을 직접 재는 대신 서버가 응답을 반환할 때 패킷 헤더에 기록하는 TCP 타임스탬프 값을 추출해 분석하는 공격이 가능하다고 한다.
클라이언트로 돌아오는 네트워크 경로가 아무리 혼잡하고 지연이 심하더라도, 서버 측 OS 커널이 응답을 생성하는 시점에 찍힌 타임스탬프를 확인하면 서버 내부의 순수한 실행 시간만을 정밀하게 역산할 수 있다.
연산 증폭 기법 (Delay-expansion)
2024년 PortSwigger 사의 연구다. 최신 웹 아키텍처(GraphQL, 무거운 ORM 객체 매핑, 정규식 등)와 결합해 시간 차이를 증폭시키는 기법이 실제로 사용되고 있다고 한다.
암호 비교에서 발생하는 아주 미세한 시간 차이를 무거운 데이터베이스 쿼리나 에러 발생 조건과 의도적으로 엮어, 그 차이를 네트워크 지연을 가볍게 무시할 수 있는 초 단위로 뻥튀기시켜 측정하는 식이다.
