TOTP / 2FA 코드 디버거
TOTP / 2FA 코드를 생성하고 디버그합니다. RFC 6238 전체 도출, 드리프트 창 검증, otpauth:// 파싱까지 모두 브라우저에서.
코드를 보려면 시크릿을 입력하세요.
otpauth://totp/user%40example.com?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&period=30여섯 자리는 실제로 무엇인가
TOTP 코드 — 인증 앱이 30초마다 넘기는 숫자 — 는 무작위가 아니며 어디에도 저장되지 않습니다. 그것은 여러분의 휴대폰과 서버 양쪽에서, 이미 공유된 두 가지 — 이중 인증을 켤 때 한 번 설정한 시크릿과 현재 시간 — 로부터 계산됩니다. 양쪽이 독립적으로 계산할 수 있으므로 로그인 시 둘 사이에 아무것도 오갈 필요가 없습니다. 서버는 같은 계산을 실행하고 그 답이 여러분의 것과 일치하는지 확인할 뿐입니다.
TOTP(RFC 6238)는 더 오래된 방식인 HOTP(RFC 4226) 위의 얇은 층입니다. HOTP는 시크릿과 카운터를 코드로 바꿉니다. TOTP는 카운터를 Unix 기원 이후의 시간 단계 수로 설정한 HOTP일 뿐입니다. 그것이 전부입니다. 현재 Unix 시간을 단계 길이(기본 30초)로 나누고 그 결과를 HOTP에 넣습니다. 코드가 검증되지 않을 때 답은 거의 항상 도출 어딘가에 보이므로, 이 도구는 그 계산의 각 단계를 보여줍니다.
도출, 한 단계씩
다섯 단계가 시크릿과 시간을 여러분이 입력하는 자릿수로 이끕니다. 도구는 각 단계를 출력하므로 자신의 구현과 비교할 수 있습니다.
- 카운터. Unix 시간을 초로 취해 T0(모든 실제 배포에서 0)를 빼고, 주기로 나눈 뒤 내림합니다. 30초 단계에서는 같은 반 분 안의 어느 순간이든 같은 카운터를 주므로, 코드가 유지되는 만큼 유지됩니다.
- HMAC. 카운터를 8바이트 big-endian으로 쓰고 선택한 해시로 HMAC(시크릿, 카운터)를 계산합니다. 거의 모든 앱은 SHA-1입니다. 이는 SHA-1에서 20바이트 다이제스트(SHA-256에서 32, SHA-512에서 64)를 만듭니다.
- 오프셋. 다이제스트 마지막 바이트의 하위 4비트를 취합니다. 0에서 15 사이의 숫자로, 다이제스트의 어디를 읽을지 알려줍니다 — 동적 절단이며, 같은 시크릿이 항상 같은 바이트를 쓰지는 않게 합니다.
- 31비트 값. 오프셋부터 4바이트를 읽고 최상위 비트를 마스킹합니다(부호 혼동을 피하려고). 31비트 정수가 남습니다.
- 코드. 그 정수를 10^자릿수로 나눈 나머지를 취하고 왼쪽을 0으로 채웁니다. 여섯 자리가 거의 보편적인 선택입니다. 일곱과 여덟도 존재하고 허용됩니다.
최상위 비트 마스킹과 나머지 연산만이 손실이 있는 단계입니다. 서로 다른 많은 다이제스트가 같은 여섯 자리로 사상되지만 괜찮습니다. 코드는 살아 있는 30초 동안만 추측하기 어려우면 되고, 영원히 고유할 필요는 없기 때문입니다.
왜 코드가 맞지 않는가 — 흔한 세 가지 원인
TOTP 불일치는 결코 오류 메시지와 함께 오지 않습니다. 코드가 그저 틀릴 뿐입니다. 실제로는 거의 항상 세 가지 중 하나이며, 여기 패널들은 그것들을 구분하도록 배치되어 있습니다.
- 시크릿을 잘못된 형식으로 읽었다. 인증 앱 시크릿은 Base32이지만, 같은 문자를 hex로 읽으면 — 또는 실제로 hex였던 시크릿을 Base32로 읽으면 — 완전히 다른 바이트와 완전히 다른 코드가 나옵니다. 형식 전환을 조작해 어느 것이 기대한 코드를 주는지 보세요.
- 매개변수가 다르다. 압도적인 기본값은 HMAC-SHA-1, 6자리, 30초 주기입니다. SHA-256, 8자리, 또는 60초 단계를 쓰는 서버는 기본값에 둔 앱과 어긋납니다. otpauth:// URI는 셋 모두를 담으므로 QR을 스캔하면 맞게 얻지만 시크릿을 손으로 입력하면 흔히 그렇지 않습니다.
- 시계가 어긋났다. TOTP는 양쪽이 시간에 대해 일치한다고 가정합니다. 휴대폰 시계가 1분 빠르면 그 코드는 서버보다 1분 앞섭니다. 드리프트 창은 그것을 위한 것입니다. 지금의 양쪽 단계에 대해 코드를 검증하면 일치 여부뿐 아니라 시계가 얼마나 어긋났는지도 알려줍니다.
RFC 6238은 각 쪽으로 최대 한 단계의 검증 창을 권장합니다. 일반적인 시계 어긋남과 전환 순간의 경쟁을 흡수하기에 충분하면서 탐색 공간을 필요 이상으로 넓히지 않습니다. 이 도구는 기본으로 ±1을 쓰고 디버깅 시 넓힐 수 있게 합니다.
시크릿, Base32, otpauth:// URI
시크릿은 설정 시 한 번 공유되고 이후 모든 것이 그것에서 도출됩니다. 인증 앱은 그것을 Base32(RFC 4648)로 인코딩합니다 — 문자 A–Z와 2–7의 알파벳으로, 혼동하기 쉬운 문자를 피하고 QR 아래 인쇄되어도 살아남습니다. 이 도구는 기본으로 Base32를 읽고 앱이 가독성을 위해 넣는 공백과 대소문자를 무시하며, 시크릿이 원시 바이트로 주어지는 RFC 6238 테스트 벡터를 재현할 수 있도록 hex도 받습니다.
설정 시 스캔하는 QR 코드도 마법이 아닙니다. 시크릿과 모든 매개변수를 담은 평문 otpauth:// URI를 인코딩할 뿐입니다. 여기에 하나 붙여넣어 필드를 채우거나, 필드에서 하나 만들어 앱 사이에 설정을 옮기세요.
otpauth://totp/GitHub:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=GitHub&algorithm=SHA1&digits=6&period=30
totp 유형만 받습니다. otpauth://hotp URI는 주기 대신 카운터를 담으며, 그것을 TOTP로 취급하면 조용히 틀린 코드를 만들므로 추측하지 않고 거부합니다.
알고리즘, 자릿수, 주기
RFC 6238은 HMAC-SHA-1, SHA-256, SHA-512, 여섯에서 여덟 자리, 임의의 단계 길이를 허용합니다. 실제로 세상은 SHA-1, 여섯 자리, 30초에 정착했고 대부분의 앱은 그 조합만 구현합니다. 그래서 다른 것을 고르는 서버는 사용자의 앱이 따라오기를 바랄 수밖에 없고 많은 앱은 따라오지 않습니다. 상호 운용을 위한 안전한 선택은 지루한 것입니다.
SHA-1 문제를 직접 다룰 가치가 있습니다. 이 사이트의 해시 도구가 SHA-1을 깨졌다고 표시하기 때문입니다. 두 진술 모두 참입니다. SHA-1은 공격자가 충돌 — 같은 해시를 가진 두 문서 — 을 만들 수 있어 디지털 서명에 쓸 수 없습니다. TOTP는 그 성질에 의존하지 않습니다. 그 보안은 해시의 충돌 저항성이 아니라 HMAC 안의 시크릿 키에서 오며, HMAC-SHA-1은 여전히 건재합니다. 여기서 SHA-256을 쓰는 것은 옹호할 만하지만 얻는 것이 적고, SHA-1만 하는 앱과의 상호 운용성을 대가로 치릅니다.
이 도구가 보호하는 것과 보호하지 않는 것
여기 모든 것은 여러분의 브라우저에서 실행됩니다. HMAC은 Web Crypto API로 여러분의 기기에서 계산되며 — 해시 도구와 HMAC 도구가 쓰는 것과 같은 프리미티브입니다 — 입력하는 어떤 것도 — 시크릿, 코드, otpauth URI — 업로드되거나 저장되거나 기록되지 않습니다. 이는 코드가 클라이언트 측이라는 성질이지, 믿어야 하는 약속이 아닙니다.
그렇지만 TOTP 시크릿은 두 번째 요소입니다. 그것을 가진 사람은 누구나 여러분의 코드를 생성할 수 있습니다. 운영 시크릿을 어떤 웹 페이지 — 이 페이지 포함 — 에 붙여넣으면 클립보드에, 어쩌면 브라우저 기록에도 들어가므로, 어떤 비밀번호와도 같은 주의로 다루고, 메커니즘만 이해하면 될 때는 일회용이나 테스트 시크릿을 선호하세요. 이 도구는 디버그와 학습을 위한 것이지 여러분의 진짜 두 번째 요소가 사는 곳이 아닙니다.
자주 묻는 질문
- 제 시크릿이 서버로 전송되나요?
- 아니요. 코드는 Web Crypto API로 브라우저에서 계산되며 입력하는 어떤 것도 업로드되거나 기록되지 않습니다. TOTP 시크릿은 두 번째 요소이므로 운영 시크릿을 붙여넣을 때는 그래도 조심하세요. 어떤 텍스트와도 같이 클립보드와 브라우저 기록을 거칠 수 있습니다.
- 왜 제 코드가 인증 앱과 맞지 않나요?
- 거의 항상 세 가지 중 하나입니다. 시크릿을 잘못된 형식으로 읽었거나(Base32 대 hex), 매개변수가 기본값과 다르거나(대부분의 앱은 SHA-1, 6자리, 30초 주기), 기기 시계가 어긋났습니다. 도출 패널이 앞의 둘을 분리하고, ± 드리프트 창 검증이 셋째를 드러냅니다.
- TOTP와 HOTP의 차이는 무엇인가요?
- HOTP(RFC 4226)는 시크릿과 사용할 때마다 증가하는 카운터에서 코드를 계산합니다. TOTP(RFC 6238)는 카운터를 Unix 기원 이후 시간 단계 수로 설정한 같은 구성으로, 코드가 버튼 누름이 아니라 시계와 함께 바뀝니다. TOTP는 인증 앱이 쓰는 것입니다.
- 다른 곳에서 깨졌는데 왜 SHA-1이 기본인가요?
- SHA-1은 충돌을 만들 수 있어 서명에는 깨졌지만, TOTP가 기반한 HMAC은 충돌 저항성에 의존하지 않습니다. 그 보안은 시크릿 키에 있습니다. HMAC-SHA-1은 건재하며 많은 인증 앱이 구현하는 유일한 알고리즘이므로, 안전하면서도 호환되는 기본값입니다.
- 코드를 특정 시간에 고정할 수 있나요?
- 네. 시간을 실시간에서 고정으로 바꾸고 Unix 타임스탬프를 입력하세요. 그러면 코드가 정적으로 유지되어, 공개된 테스트 벡터를 재현하거나(RFC 6238은 59와 1111111109 같은 시간에서 값을 줍니다) 과거 순간에 어떤 코드가 유효했는지 확인할 수 있습니다.
- 드리프트 창은 얼마나 커야 하나요?
- RFC 6238은 각 쪽으로 최대 한 단계를 권장하며, 이 도구가 기본으로 씁니다. 더 넓은 창은 더 어긋난 시계를 허용하지만 서버가 받아들일 코드 집합도 넓히므로 절충입니다. ±1이 표준 균형입니다.
- 자릿수와 주기는 무엇을 위한 건가요?
- 자릿수는 코드의 숫자 개수입니다 — 거의 어디서나 여섯, 서비스가 조금 더 강도를 원하는 곳에서 일곱이나 여덟. 주기는 코드가 유효한 초 수로 기본 30초입니다. 둘 다 otpauth:// URI에 들어가며, 둘 다 양쪽에서 일치해야 코드가 맞습니다.