먼저 결론입니다. 로컬 취약 비밀번호 목록이 지지할 수 있는 것은 「이 문자열이 이미 널리 남용되는 비밀번호처럼 보이는가」라는 좁은 사실뿐입니다. 미적중은 어떤 유출에도 한 번도 나오지 않았다는 증명이 아닙니다. 적중은 너무 흔하니 지금 바꾸라는 뜻뿐입니다. Have I Been Pwned의 비밀번호 범위 조회는 다른 프로토콜이며, 보내는 것은 SHA-1 앞 5자리입니다. 임의의 「온라인 유출 확인」칸에 원문을 붙이기 전에, 지금부터 돌릴 것이 셋 중 어느 것인지 확인하세요.
검색 의도를 한 문장으로 먼저 답하기
로컬 취약 비밀번호 목록이 증명할 수 있는 것은 한 가지뿐입니다. 지금 입력한 문자열이, 「이미 이 탭으로 내려받은 공개 고빈도 목록」에 맞는가, 맞지 않는가. 「전 웹에서 본 적 없다」는 증명이 되지 않으며, 「내 이메일이 어느 유출에 들어갔는가」에도 답하지 않습니다. Have I Been Pwned(HIBP)의 Pwned Passwords 범위 조회는 다른 길입니다. 이 기기에서 SHA-1을 계산하고, 십육진 앞 5자리만 https://api.pwnedpasswords.com/range/{prefix}로 보내며, 나머지 접미사는 클라이언트에서 대조합니다.
이 글은 예전 비밀번호를 「한번 확인해 보고 싶은」 개발자와 운영, 그리고 동료가 「온라인 비밀번호 유출 확인」 링크를 넘겨 준 고객지원을 위한 것입니다. 비밀번호 강도 검사의 사용 설명을 대신하지 않으며, 「로컬 암호화가 원문을 올렸는가」라는 Network 총론도 반복하지 않습니다. 가져가야 할 것은 세 조회가 이 기기에서 무엇을 내보내는지, 로컬 목록이 어느 변형까지 보는지, 적중과 미적중이 티켓에 쓸 수 있는 문장은 어느 것인지입니다.
세 가지 「유출 확인」은 같은 일이 아닙니다
한국어로 「비밀번호 유출 확인」이나 「비밀번호 유출 조회」를 검색하면, 결과 페이지는 전혀 다른 프로토콜을 한줄에 늘어놓습니다. 입력칸의 글자를 그대로 POST하는 사이트, HIBP의 k-익명성 범위 API를 부르는 사이트, 짧은 단어표만 받아 브라우저에서 사전 조회하는 사이트. 셋 모두 화면에는 「발견되지 않음」이나 「유출됨」을 찍을 수 있습니다. 요청 줄은 다르고, 지지할 수 있는 결론도 다릅니다.
한국에서 자주 섞이는 세 번째 축이 하나 더 있습니다. 행정안전부의 털린 내 정보 찾기는 이메일, 전화번호, 아이디가 국내 유출 사고에 있는지 조회하는 쪽에 가깝습니다. 비밀번호 문자열 자체를 사전과 대조하는 일이 아닙니다. Have I Been Pwned의 비밀번호 조회가 답하는 것도 「이 이메일과 이 비밀번호의 짝이 다른 사이트에 있는가」가 아니라, 「이 비밀번호 문자열의 해시가 지금 색인에 있는가」입니다. 셋이 모두 「유출 확인」으로 불리므로, 티켓에 「조회했음, 유출 없음」만 있으면 다음 사람은 어느 그물을 썼는지 알 수 없습니다.
공격 쪽도 흔히 셋으로 나눕니다. 흔한 단어를 순서대로 대입하는 사전 공격, 가능한 조합을 모두 시도하는 무차별 대입, 다른 서비스에서 샌 아이디·비밀번호 짝을 다른 사이트에 넣어 보는 크리덴셜 스터핑(리스트형 공격). 로컬 고빈도 목록이 직접 막을 수 있는 것은 사전의 입구, 즉 123456이나 password처럼 이미 닳은 문자열입니다. 리스트형 공격의 본체, 「이 메일과 이 비밀번호의 짝이 다른 유출에 있었는가」는 짧은 공개 목록으로는 답할 수 없습니다.
OWASP Authentication Cheat Sheet는 가입과 비밀번호 변경 흐름에서 「흔하거나 이미 유출된 비밀번호를 거절하라」고 적고, Pwned Passwords와 SecLists 같은 공개 목록을 함께 지목합니다. 팔백 줄 남짓한 로컬 목록과 십억 규모 해시 창고를 같은 증거로 적지는 않습니다.
| 방식 | 이 기기를 떠나는 것 | 미적중에서 쓸 수 있는 문장 |
|---|---|---|
| 원문 또는 전체 해시 업로드 | 비밀번호 자체, 또는 복원·대조에 충분한 완전한 요약 | 상대 사이트가 이번에 빨간 표시를 내지 않았다는 것뿐. 안전의 증명이 아님 |
| HIBP 범위 조회 | SHA-1 또는 NTLM의 십육진 앞 5자리 | HIBP의 현재 색인에 이 해시는 없었다 |
| 이 기기의 공개 고빈도 목록 | 목록 파일 자체. 검사할 비밀번호는 탭에 남음 | 이 짧은 목록과 그 변형 규칙에는 맞지 않았다 |
세 번째에도 통신은 있습니다. 브라우저는 목록 파일을 GET합니다. 그것은 공개 단어표이며, 당신의 비밀번호가 아닙니다. 「둘 다 네트워크를 탔으니 둘 다 업로드다」로 묶으면 경계를 오해합니다. 반대로 페이지에 「로컬」이라고 적혀 있는 것 자체를 증거로 쓰면, 첫 번째 사이트를 놓칩니다.
지금 쓰는 운영 금고 비밀번호, 아직 돌리지 않은 API 토큰, 개인 인터넷뱅킹 비밀번호로 실험하지 마세요. 이번 확인에만 나오는 가짜 비밀번호를 카나리아로 쓰세요. 예는 CanaryPwd-20260902-xK9입니다. 확인하는 것은 요청이 이 문자열을 실었는지이지, 진짜 비밀을 한 번 더 드러내는 일이 아닙니다.
로컬 목록이 실제로 대조하는 것
FastPwd 비밀번호 강도 검사를 예로 듭니다. 목록은 같은 출처의 data/leaked-top10k.txt에서 페이지와 함께 내려받고, 이 기기에서 소문자 키에서 순위로 가는 표를 만듭니다. 파일 이름의 top10k는 공개 고빈도 목록에 흔한 이름입니다. 그 요청의 응답을 열면 빈 줄을 빼고 팔백 줄이 조금 넘고, 앞줄은 123456, password, qwerty처럼 반복해서 나온 비밀번호입니다. 제품 문장은 이것을 「만 건」이라고도, 「전 웹 유출 집합」이라고도 쓰지 않습니다.
대조는 완전 일치를 한 번 하고 끝이 아닙니다. 구현은 네 단계이며, 어느 한 단계라도 맞으면 빨갛게 표시하고 등급을 강제로 약함으로 내립니다.
- 완전 일치: 입력이 목록 항목과 한 글자도 다르지 않음.
- 대소문자 무시: 먼저 소문자로 바꾼 뒤 찾음.
Password와password는 같은 한 줄. - 끝자리 0–999 제거:
qwerty123은 먼저qwerty로 줄인 뒤 찾음. - 흔한 Leet:
@/4→a,3→e,1/!→i,0→o,5/$→s,7→t. 끝자리 숫자를 먼저 뗀 뒤에 이 치환을 해도 됩니다.
입력이 128자를 넘으면 뒤의 두 단계는 돌지 않고, 완전 일치와 대소문자만 남습니다. 목록을 읽지 못하면 내장 최소 집합으로 떨어집니다. password, 123456, 12345678, qwerty, admin123입니다. 상태 줄에는 검사가 여전히 이 기기에서 끝났다고 나옵니다. 순위는 힌트용입니다. 상위 100, 상위 500, 상위 1000, 또는 「공개 유출 목록」으로 되돌림. HIBP처럼 「몇 번 나왔는가」의 횟수가 아닙니다.
NIST SP 800-63B-4는 개설과 변경 때 후보 비밀번호를 「흔하거나, 예측 가능하거나, 이미 유출된」 차단 목록과 문자열 전체로 대조하라고 적습니다. 부분 문자열이 아니며, 복잡도 규칙을 겹쳐 쌓는 것도 권하지 않습니다. 로컬 고빈도 목록은 「가장 자주 맞춰지는 한 무리를 먼저 막는」 층에는 맞습니다. 다만 목록의 부피는 공격자가 가진 완전한 사전보다 작고, HIBP가 계속 합치는 유출 해시보다 훨씬 작습니다. 2026년 6월, HIBP는 June 2026 Stealer Logs 한 배치만으로 중복을 뺀 약 1억 2,400만 개의 비밀번호를 넣었습니다. 팔백 줄 남짓한 공개 고빈도 단어는 123456은 잡습니다. 어떤 사내 유출에 한 번만 나온 긴 문장은 잡지 않습니다.
HIBP 범위 조회가 보내는 것과 보내지 않는 것
HIBP의 비밀번호 페이지 자신이 이렇게 적습니다. 찾지 못했다는 것은 「좋은 비밀번호」라는 뜻이 아니라, 「이 사이트의 색인에 없다」는 뜻뿐입니다. 범위 조회의 절차는 API v3 · Pwned Passwords에 있습니다. 클라이언트는 먼저 비밀번호의 SHA-1(또는 mode=ntlm이면 NTLM)을 구하고, 십육진 앞 5자로 GET https://api.pwnedpasswords.com/range/{prefix}를 호출합니다. 서버는 그 접두사 아래의 접미사와 출현 횟수를 모두 돌려줍니다. 40자리 해시의 뒤 35자리는 이 기기에서 대조합니다.
공식 규모는 그 자리에서 맞춰 볼 수 있습니다. 범위 조회는 보통 약 800개의 접미사를 돌려줍니다. 접두사 공간은 165 = 1,048,576개이며, 00000부터 FFFFF까지 모두 HTTP 200을 돌려줘야 하고 404가 나와서는 안 됩니다. 선택 헤더 Add-Padding: true는 응답을 800–1000줄로 채워, 옆에서 응답 길이로 접두사를 추측하기 어렵게 합니다. Cloudflare는 Validating Leaked Passwords with k-Anonymity에서 이 범위 조회를 k-익명성이라고 부릅니다. 서버는 아직 유출되지 않은 비밀번호의 전체 해시를 받지 못하므로, 나중에 이번 조회만 「풀어」 낼 수도 없습니다.
이메일 조회는 다른 길입니다. 공식 설명대로, 이메일을 경로에 그대로 두면 그 주소를 HIBP에 넘깁니다. 이메일을 k-익명성으로 조회하려면 보내는 것은 이메일 SHA-1의 앞 6자리이며, 비밀번호의 앞 5자리가 아닙니다. 티켓에 「HIBP에서 조회했다」고 쓸 때는 비밀번호 해시 접두사를 봤는지, 이메일을 봤는지를 적으세요. 개인정보 경계도, 결론도 다릅니다. 한국에서 이메일이 국내 사고에 있는지 보고 싶다면 털린 내 정보 찾기가 그 질문에 가깝고, 비밀번호 문자열이 공개 사전에 있는지를 보는 일과는 바꿔 쓸 수 없습니다.
FastPwd는 위의 HIBP 인터페이스를 어느 쪽도 호출하지 않습니다. 비밀번호 강도 검사가 할 수 있는 것은 이 기기에서의 엔트로피 추정과 이 공개 고빈도 목록입니다. 십억 규모 해시 창고와 대조하려면 HIBP 공식 페이지나 직접 둔 오프라인 사본을 쓰고, Network에서 요청 줄에 다섯 자리 접두사만 있는지 직접 확인하세요. 「보안 도구라면 대신 HIBP를 조회해 줄 것」이라고 가정하지 마세요.
Network로 검사할 비밀번호가 나갔는지 그 자리에서 확인하기
페이지의 「올리지 않음」은 증거가 되지 않습니다. 카나리아 문자열은 증거가 됩니다. 절차는 「로컬 암호화가 원문을 실었는가」와 같은 계열이나, 보는 대상은 비밀번호 칸과 목록 파일입니다.
- 개발자 도구 Network를 열고 Preserve log를 켭니다. 필터는 먼저 비워 두어 분석 전송을 놓치지 않게 합니다.
- 비밀번호 강도 검사에 카나리아를 넣습니다. 예는
CanaryPwd-20260902-xK9. 마지막 입력 후 약 280밀리초의 로컬 계산이 끝날 때까지 기다립니다. - 요청 목록에서 이 카나리아를 검색합니다. 요청 줄, Query, 본문, 폼 필드 어디에도 나오면 안 됩니다.
- 같은 출처의 GET
data/leaked-top10k.txt는 보여야 합니다. 응답을 열어 한 줄에 공개 비밀번호 하나인지, 방금 넣은 카나리아가 없는지 확인합니다. - 사이트가 HIBP 연동을 주장하면 따로
api.pwnedpasswords.com/range/를 찾습니다. 경로에 있어야 하는 것은 십육진 다섯 자리뿐이며, 원문은 나오면 안 됩니다.
접속 통계는 있어도 됩니다. FastPwd의 검사 이벤트가 보내는 것은 이벤트 이름뿐입니다. 「검사 시작」, 「결과 약함」, 「유출 목록 적중」처럼이며, 입력칸 내용을 인자로 쓰지 않습니다. Network에서 /tj/matomo.php로 가는 전송을 열고 카나리아를 검색해, 적중이 없는지 보세요. 탭을 닫은 뒤 이번 입력은 FastPwd 서버에 남지 않습니다. 다만 전제는 업무 데이터로 한 번도 도착하지 않았다는 것입니다. 지지하는 것은 방금의 검색입니다. 「페이지를 닫았다」로는 지지할 수 없습니다.
카나리아가 어떤 요청에라도 나오면 결론은 뒤집힙니다. 버튼에 「로컬」이나 「개인정보」라고 적혀 있어도, 이번 검사는 비밀번호를 탭 밖으로 보낸 것입니다. 도구를 바꾸거나, 이 기기만의 목록으로 바꾼 뒤 같은 절차를 반복하세요.
적중과 미적중이 각각 지지할 수 있는 것
적중했을 때 티켓에 써도 되는 문장은 이렇습니다. 「이 문자열은 페이지와 함께 내려받은 공개 고빈도 목록에 어느 단계에서 맞았다(완전 일치 / 대소문자 / 끝자리 숫자 / Leet). 이 기기의 규칙에서는 극히 흔한 취약 비밀번호이므로 바꿔야 하며, 다른 사이트에서도 재사용하지 않는다.」 쓰면 안 되는 문장은 「상대 서버가 몇 년 어느 유출의 원문이라고 확인했다」입니다. 이 기기 목록에는 사고 이름도 출현 횟수도 없고, 있는 것은 순위 힌트뿐입니다.
미적중일 때 쓸 수 있는 문장은 더 짧습니다. 「지금 이 공개 고빈도 목록과 네 단계 변형에서는 맞지 않았다.」 쓰면 안 되는 문장은 「한 번도 유출되지 않았다」, 「이대로 써도 된다」, 「HIBP보다 깨끗하다」입니다. 팔백 줄 남짓한 고빈도 표는 원래 「안전의 증명」용이 아닙니다. 공격자의 살포 사전, 사내 예전 비밀번호, 한 번의 비공개 유출에만 나온 긴 문장은 이 표에 없습니다.
엔트로피 추정은 세 번째 평행 정보입니다. 페이지는 길이와 문자 종류로 bits를 봅니다. 80 이상은 매우 강함, 60 이상은 강함, 40 이상은 보통, 나머지는 약함. 오프라인 무차별 대입은 초당 약 100억 회, 온라인 제한 아래는 초당 약 1000회로 시간 자릿수를 냅니다. 8자 미만이거나 내장된 흔한 취약 비밀번호에 맞으면 등급은 약함으로 눌립니다. 숫자는 상대적인 강약을 비교하기 위한 것이며, 카운트다운 약속이 아닙니다. 공개 목록에 적중하면 엔트로피가 높아도 약함으로 바뀝니다. 사전 공격은 「평균 무차별 대입」이라는 길을 걷지 않기 때문입니다.
자주 묻는 질문
취약 비밀번호 목록에 미적중하면, 한 번도 유출되지 않았다는 뜻인가요?
아닙니다. 미적중이 뜻하는 것은, 지금 연 탭의 공개 고빈도 목록에서 완전 일치, 대소문자 무시, 끝자리 0–999 제거, 흔한 Leet 치환이 모두 맞지 않았다는 것뿐입니다. 어떤 유출에도 한 번도 나오지 않았다는 증명도, Have I Been Pwned에 없다는 증명도, 계속 재용해도 된다는 증명도 아닙니다.
Have I Been Pwned로 비밀번호를 조회하면 원문이 나가나요?
공식 API를 따르면 나가지 않습니다. Pwned Passwords 범위 조회가 받는 것은 SHA-1 또는 NTLM 해시의 앞 5자리뿐이며, 돌아오는 것은 약 800개의 접미사입니다. 완전한 대조는 클라이언트에 남습니다. 원문과 전체 해시는 요청에 나오면 안 됩니다. 이메일 주소로 유출을 조회하는 것은 다른 API이며, 주소를 경로에 두면 그 주소를 상대에게 넘깁니다. 판단 기준은 Network에서 본 그 한 줄입니다. 버튼 문구가 아닙니다.
FastPwd 비밀번호 강도 검사는 Have I Been Pwned를 조회하나요?
하지 않습니다. 대조하는 것은 페이지와 함께 이 기기로 내려받는 공개 고빈도 취약 비밀번호 목록입니다. 검사할 비밀번호는 HTTP 업무 데이터로 나가지 않고, 접속 분석에도 쓰지 않습니다. 분석이 기록하는 것은 「검사 시작」, 「결과 약함 / 보통 / 강함」 같은 이벤트 이름뿐입니다. 열어 바로 쓰며 계정은 필요 없고, 검사 기록을 남길 비밀번호 보관함도 없습니다.
엔트로피가 높아도 목록에 적중하면 강한 비밀번호인가요?
이 기기의 규칙에서는 공개 취약 비밀번호 목록에 적중하는 순간 강제로 「약함」이 됩니다. 엔트로피가 추정하는 것은 문자 공간의 무차별 대입 비용입니다. 목록이 답하는 것은 「공격자 사전에 이 문자열이 이미 있는가」입니다. 두 질문은 서로를 상쇄하지 않습니다. NIST SP 800-63B-4는 복잡도나 정기 변경이 아니라, 흔하거나 이미 유출된 비밀번호의 전체 문자열 차단 목록을 검증 쪽에 요구합니다.
가짜 비밀번호로 절차를 끝까지 걷기
계산 경계가 문장으로 적혀 있는 페이지에서 연습하려면 FastPwd 비밀번호 강도 검사를 여세요. 열어 바로 쓰며 가입은 필요 없습니다. 먼저 password나 qwerty123을 넣으면 공개 목록에 적중하고 강제로 약함이어야 합니다. 이어서 위의 카나리아를 넣으면 목록에는 맞지 않고, Network에서 그 문자열은 찾지 못해야 합니다. 목록 파일 GET을 열어 줄 수를 세면, 본문의 「팔백 줄 남짓한 고빈도 단어」와 맞출 수 있습니다.
약함으로 나오면 비밀번호 생성기에서 이 기기에 새 문자열을 뽑으세요. 무작위 모드는 6–128자, 기본값은 16자이며, 8자 미만이면 보안이 낮다고 알려 줍니다. 새 비밀번호를 동료에게 넘겨야 하면 열람 후 파기로 바꾸세요. 이 기기에서 AES-256-GCM으로 암호화하고, 서버가 잠시 두는 것은 암호문뿐이며, 키는 링크의 # 뒤에 남습니다. 완성된 열람 후 파기 링크를 어떤 「온라인 유출 확인」 입력칸에도 다시 붙이지 마세요.
이 연습의 목적은 어떤 사이트가 「절대 안전하다」를 증명하는 일이 아닙니다. 검사를 누르기 전에 동료에게 보여 줄 수 있는 대조를 손에 쥐는 일입니다. 이번이 원문 업로드인지, 해시 접두사인지, 이 기기의 짧은 목록인지. 적중하면 바꾼다. 미적중을 「한 번도 유출되지 않았다」고 쓰지 않는다. 같은 절차는 임의의 「보안 점수」나 「유출 조회」 확장에도 다시 쓸 수 있습니다.
다음에 누군가 비밀번호를 검사칸에 넣을 때, 먼저 셋을 물으세요. 첫째, 요청에 원문이나 전체 해시가 있는가. 둘째, 대조하는 것이 팔백 개의 고빈도 단어인가, HIBP 같은 범위 조회인가. 셋째, 미적중일 때 티켓에 어느 한 줄을 쓸 생각인가. 반복할 수 있는 대조라야 팀의 비밀번호 규정에 넣을 가치가 있습니다.
이어서 읽기
검사 페이지 자체가 원문을 보냈는지 보려면 같은 카나리아로 더 긴 Network 절차를 걷으세요. 브라우저 로컬 암호화에서 원문이 이 기기를 떠나지 않았는지 확인하는 방법. 완전한 비밀을 검사칸이 아니라 사람에게 넘겨야 할 때는, 키를 # 뒤에 둘 수 있는 이유와 그 층이 깨지는 장면입니다. URL 해시 뒤에 키를 두는 이유, 그리고 그 보호가 깨질 때. 티켓과 로그를 AI에 붙이기 전의 항목 단위 대조는 티켓과 로그를 AI에 붙이기 전에, 어떤 항목이 이 기기를 떠나는지 먼저 확인하는 방법입니다.