TOTP & HOTP
TOTP(시간 기반 일회용 비밀번호, RFC 6238)와 HOTP(HMAC 기반 일회용 비밀번호, RFC 4226)는 모든 2FA 등록 QR이 구현하는 두 가지 RFC예요. 인코딩된 otpauth:// URI 스킴은 Google Authenticator의 사실상 표준이며, 모든 주요 인증 앱과 호환돼요.
TOTP 사양:RFC 6238 (시간 기반, 2011).
HOTP 사양:RFC 4226 (카운터 기반, 2005).
URI 스킴:Google Authenticator Key URI Format, 모든 인증 앱이 동의하는 형식이에요.
HOTP 사양:RFC 4226 (카운터 기반, 2005).
URI 스킴:Google Authenticator Key URI Format, 모든 인증 앱이 동의하는 형식이에요.
개요
2FA 등록 QR은 공유 시크릿과 식별 메타데이터를 담는 otpauth:// 스킴의 URL이에요. 형식:
otpauth://TYPE/LABEL?secret=SECRET&issuer=ISSUER&algorithm=ALG&digits=N&period=SEC- TYPE,
totp(시간 기반) 또는hotp(카운터 기반). - LABEL,
Issuer:Account, URL 인코딩됨. 예:GitHub:alice@example.com. - secret, 공유 키, Base32 인코딩(RFC 4648 §6 알파벳: A-Z, 2-7).
- issuer, 인증 앱에 표시되는 서비스 이름. 라벨을 파싱하지 않는 앱의 UX를 개선하기 위해 라벨과 중복돼요.
- algorithm,
SHA1(기본값),SHA256또는SHA512. 모든 인증 앱이 SHA1 지원. SHA256/SHA512는 소수만 지원. - digits,
6(기본값) 또는8. 대부분의 소비자 앱은 6을 기대해요. - period, TOTP만.
30(기본값) 또는60초. HOTP는 대신counter파라미터를 가져요.
표준 테스트 벡터
| 케이스 | 입력 | 기대되는 otpauth:// URI |
|---|---|---|
| TOTP, 최소 (SHA1, 6자리, 30초) | issuer=GitHub | otpauth://totp/GitHub:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub |
| TOTP, SHA256, 8자리 | issuer=Corp | otpauth://totp/Corp:bob?secret=JBSWY3DPEHPK3PXP&issuer=Corp&algorithm=SHA256&digits=8 |
| HOTP, counter=0 | issuer=YubiKey | otpauth://hotp/YubiKey:carol?secret=JBSWY3DPEHPK3PXP&issuer=YubiKey&counter=0 |
| TOTP, RFC 6238 참조 시크릿 | issuer=Example | 표준 RFC 테스트 시크릿 (12345678901234567890). T=59초에서 TOTP 94287082를 생성해요. |
라이브 Base32 시크릿 검증기
인증 앱은 Base32 알파벳(A-Z, 2-7) 이외의 문자를 포함한 시크릿을 거부해요. 아래는 TOTP 생성기가 인라인으로 실행하는 것과 동일한 검증기예요. 브라우저에서 실행돼요.
시크릿을 입력해 확인하세요.
흔한 함정
- Base32는 Base64가 아니에요. Base64는 A-Z, a-z, 0-9, +, /를 사용해요. 시크릿에 소문자나 0, 1, 8, 9가 있으면 Base64 문자열이 전달된 것이고 모든 인증 앱에서 거부돼요.
- 시크릿 길이. RFC 4226 §4는 HOTP에 최소 128비트(26 Base32 문자), TOTP에 160비트(32문자)를 권장해요. 80비트(16문자) 미만의 시크릿은 기술적으로는 합법이지만 취약하다고 표시돼요.
- 알고리즘 지원은 다양해요. Google Authenticator는
algorithm파라미터를 무시하고 항상 SHA1을 사용해요. SHA256/SHA512가 실제로 적용되려면 사용자가 1Password, Authy, Bitwarden 또는 Microsoft Authenticator를 사용해야 해요. - 자릿수 지원은 다양해요. 대부분의 인증 앱은
digits=8을 무시하고 6으로 자르게 돼요. 8자리 OTP가 중요하면 배포 전에 대상 인증 앱에서 테스트하세요. - 라벨을 URL 인코딩하세요. issuer나 계정의 특수 문자(
:,@, 공백)는 라벨에서 퍼센트 인코딩되어야 해요. 그렇지 않으면 구형 인증 앱이 라벨을 완전히 삭제해요. Abundera가 자동으로 처리해요. - 시크릿을 재사용하지 마세요. 모든 계정에 새로운 암호학적으로 랜덤한 시크릿이 필요해요. 서비스 간 시크릿 재사용은 하나가 침해되면 모두 위험해져요.
- 저장소가 QR보다 중요해요. QR은 일회성 부트스트랩이에요. 인증 앱은 첫 번째 스캔 후 시크릿을 저장해요. 나중에 그 시크릿이 평문으로 내보내지면 디스크 유출 하나로 모든 2FA가 위험해져요.
인증 앱 호환성
| 앱 | TOTP SHA1 | TOTP SHA256/512 | HOTP | 8자리 | 비고 |
|---|---|---|---|---|---|
| Google Authenticator | 예 | 무시됨 | 예 | 무시됨 | 사실상 기준. 항상 이것을 첫 번째 대상으로 삼아요. |
| 1Password | 예 | 예 | 예 | 예 | 완전한 RFC 지원. |
| Authy | 예 | 예 | 아니오 | 예 | 최신 버전에서 HOTP 제거. |
| Bitwarden | 예 | 예 | 예 | 예 | 완전한 RFC 지원. |
| Microsoft Authenticator | 예 | 예 | 예 | 예 | 완전한 RFC 지원. |
| YubiKey Authenticator | 예 | 예 | 예 | 예 | HOTP는 YubiKey OATH의 표준 모드예요. |
| Duo Mobile | 예 | 무시됨 | 아니오 | 무시됨 | 자체 푸시 플로우 사용. TOTP는 폴백만. |
관련 항목
- /totp-2fa-qr-code/, Base32 검증기가 내장된 TOTP 생성기.
- /hotp-qr-code/, HOTP 카운터 기반 버전.
- /standards/, 표준 인덱스로 돌아가기.