랜덤 토큰 생성기

브라우저 CSPRNG로 시크릿 생성 — 16진수, base64url, 사용자 정의 문자 집합, EFF 다이스웨어 패스프레이즈. 엔트로피를 비트로 표시.

생성 중…
엔트로피192.0 비트

세 가지 추측 속도에서의 평균 발견 시간입니다. 속도 사이의 격차가 시크릿 자체가 만드는 어떤 차이보다도 큽니다.

  • 속도 제한이 있는 로그인에 대해 — 초당 10회10^49년
  • 유출된 느린 해시(bcrypt, argon2)에 대해 — 초당 10⁴회10^46년
  • 유출된 빠른 해시(SHA-256, MD5)에 대해 — 초당 10¹²회10^38년

64개 문자에서 뽑으므로 한 글자당 6.00비트를 지닙니다.

이 도구가 하는 일

시크릿을 냅니다: 유일한 방어가 아무도 추측할 수 없다는 것인 값입니다. API 키나 데이터베이스 비밀번호에는 문자 집합과 길이를 고르거나, 사람이 쳐야 하는 것에는 공개된 단어 목록에서 뽑은 패스프레이즈로 바꾸세요. 모든 결과는 브라우저 안에서 생성되고 그 강도를 정직하게 기술하는 하나의 수와 함께 보입니다.

이것은 이 사이트의 UUID 생성기와 다른 일입니다. UUID는 고유해야 해서 두 레코드가 결코 충돌하지 않고, 시크릿은 추측할 수 없어야 하는데, 이는 더 강한 요구이자 다른 실패입니다. 예측 가능한 식별자는 무해합니다. 예측 가능한 시크릿은 열린 문입니다.

난수가 어디서 오는가

여기서는 모든 것이 crypto.getRandomValues, 브라우저의 암호학적으로 안전한 난수 생성기에서 뽑고, 그것은 운영체제의 엔트로피 풀 — openssl rand와 /dev/urandom이 쓰는 같은 원천 — 에서 씨를 받습니다.

대안인 Math.random은 보안 함수가 아니고 그렇다 주장한 적도 없습니다. 작은 내부 상태를 지닌 빠른 의사 난수 생성기이고, 현행의 모든 엔진에서 그 상태는 짧은 출력의 연속에서 복원할 수 있으며, 그 뒤로는 과거와 미래의 모든 값이 알려집니다. 그것으로 만든 토큰은 진짜만큼 랜덤해 보입니다. 차이는 누군가 굳이 볼 때만 드러납니다.

합당한 물음은 웹 페이지가 애초에 운영 시크릿을 생성할 옳은 곳인가입니다. 생성 자체는 건전합니다: 플랫폼 CSPRNG이고, 페이지는 정적이며, 아무것도 전송되지 않습니다. 생각할 만한 부분은 그 둘레의 것입니다 — 클립보드를 거치는 시크릿은 다른 애플리케이션에 읽힐 수 있고, 터미널에 붙여넣은 것은 대개 셸 기록에 떨어집니다. 그것들은 다른 어떤 방법과도 같은 고려 사항입니다.

뻔한 구현에 숨은 편향

랜덤 바이트를 문자로 바꾸는 것은 한 줄처럼 보입니다: 바이트를 취해 문자 집합 크기로 나눈 나머지를 취해 문자 집합에 인덱싱합니다. 그것은 크기가 256을 고르게 나누지 못하는 모든 문자 집합에서 미묘하게 틀리고, 출력은 그 낌새를 주지 않습니다.

62개 영숫자로는 256이 고르게 나뉘지 않습니다: 62는 256에 네 번 들어가고 8이 남습니다. 그 남은 8개의 바이트 값 — 248에서 255 — 은 문자 집합의 첫 8개 문자로 되접혀, 그것들이 256 중 다섯 기회를 얻는 반면 나머지는 넷을 얻습니다. 첫 여덟 문자가 나머지보다 약 25% 더 나올 확률입니다.

고치는 법은 기각 샘플링입니다: 남은 꼬리에 떨어진 뽑기를 되접지 않고 버리고 다시 뽑습니다. 62개 문자 집합에는 서른두 번에 약 한 번의 여분 뽑기가 들고, 크기가 2의 거듭제곱이라 꼬리가 없는 16진수나 base64url에는 전혀 들지 않습니다. 이 도구는 기각합니다. 그 효과는 어느 단일 토큰에도 보이지 않고, 바로 그래서 말할 만합니다.

엔트로피, 유일하게 정직한 척도

비트로 된 엔트로피는 똑같이 있을 법한 시크릿의 공간이 얼마나 큰지 말합니다: n비트는 2^n의 가능성을 뜻합니다. 더해지고 비교하기 쉬우며, 누가 그 공간을 얼마나 빨리 뒤질 수 있는지에 대해서는 아무것도 말하지 않습니다 — 그것은 특징입니다. 그 부분이 생성기가 알 수 없는 것에 달렸기 때문입니다.

산술은 일부러 단순합니다. 각 문자가 log2(문자 집합 크기) 비트를, 각 단어가 log2(단어 목록 크기)를 기여하므로:

  • 16진수 문자는 4비트라, 32자 16진수 토큰은 정확히 128비트 — 써낸 AES-128 키입니다.
  • base64url 문자는 6비트라, 22자가 128비트를, 43자가 256비트를 넘습니다.
  • 영숫자 문자는 약 5.95비트입니다. 닮은꼴을 빼면 문자 집합이 58로, 문자가 5.86으로 떨어져, 열두 자마다 약 한 자의 길이가 듭니다.
  • EFF 긴 목록의 단어는 12.925비트입니다. 목록에 7776개 항목 — 6^5, 주사위 다섯 번 — 이 있기 때문입니다.
  • EFF 짧은 목록의 단어는 10.34비트로, 1296개 항목 — 6^4 — 에서입니다.

흔한 목표는 128비트로, 전수 공격이 그저 비싼 것을 넘어 전략이기를 그치는 곳입니다. 그것은 32자 16진수, 22자 base64url, 또는 EFF 긴 목록의 10단어입니다.

단일 "해독 시간"이 없는 이유

시크릿에는 해독 시간이 없습니다. 시크릿과 그것을 지키는 무언가의 쌍에 하나가 있고, 지키는 것이 시크릿보다 훨씬 중요합니다. 로그인 폼을 통해 찾으려면 우주가 존재해 온 것보다 오래 걸릴 같은 값이, 솔트 없는 SHA-256으로 저장되고 데이터베이스가 새면 오후 한나절에 떨어집니다.

그래서 하나의 수가 아니라 세 속도가 보이고, 각각 이름 붙습니다:

  • 초당 열 번, 속도 제한이 있는 로그인에 대해. 당신의 서비스를 거쳐야 하는 공격자에게 현실적인 천장입니다.
  • 초당 만 번, 느리도록 만든 유출된 비밀번호 해시에 대해 — 현대 비용의 bcrypt, 또는 argon2. 그 느림이 그 함수들의 온전한 요점입니다.
  • 초당 1조 번, 비밀번호용으로 결코 뜻하지 않은 유출된 해시에 대해. SHA-256과 MD5는 빠르도록 설계되었고, GPU 장비는 참으로 빠릅니다.

속도는 일부러 10의 거듭제곱으로 반올림됩니다. 더 정밀한 것은 유용한 정보가 첫 행과 마지막 행 사이의 11자릿수일 때 한 특정 공격자의 측정을 시사할 것입니다. 시크릿이 셋 모두에서 편안하면 정확한 수치 없이 물음이 결판납니다.

각 수치는 평균으로, 전부가 아니라 공간의 절반입니다 — 탐색이 평균적으로 절반에서 답을 찾습니다. 그리고 100만 년을 넘으면 답이 자릿수로 주어집니다. "400조 년"은 누구도 비교할 수 있는 기간이 아니기 때문입니다. 우주는 약 10^10년 되었고, 그것이 그만큼 닿는 행에 유용한 닻이 됩니다.

패스프레이즈, 그리고 그 강도가 실제로 어디서 오는가

패스프레이즈가 강한 것은 딱 한 이유입니다: 몇 단어가 큰 목록에서 랜덤으로 골라졌기 때문입니다. 길어서 강한 것도, 언어처럼 보여서 강한 것도 아닙니다. 7776단어 목록에서 여섯 랜덤 단어는 약 77비트이고, 사람이 생각해 낸 여섯 단어는 훨씬 가치가 낮습니다. 사람은 고르게 고르지 않고, 공격자는 흔한 구절에 대해 당신과 같은 것을 알기 때문입니다.

여기 두 목록은 EFF에서 왔고 공개된 다이스웨어 목록으로, 바뀌지 않고 내려받은 것입니다. 여기서 짜맞춘 목록이 아니고, 그것이 중요합니다: 누군가 지어낸 단어 목록은 크기가 알려지지 않고, 다른 목록과의 겹침이 알려지지 않으며, 그것에 대해 한 엔트로피 주장을 확인할 방법이 없습니다.

  • 긴 목록은 7776단어로, 주사위 다섯 번의 각 눈에 하나이고, 단어당 12.925비트를 줍니다.
  • 짧은 목록은 1296단어로, 주사위 네 번의 각 눈에 하나이고, 단어당 10.34비트를 줍니다. 그 단어는 더 짧아 — 어느 것도 다섯 글자를 넘지 않습니다 — 치기 쉬운 대신 같은 강도에 더 많은 단어가 듭니다.

패스프레이즈의 반복된 단어는 흠이 아니고 여기서 다시 생성되지 않습니다. 각 뽑기가 독립이라 어느 특정한 단어 쌍도 다른 어떤 것과 똑같이 있을 법하고, 반복을 거부하면 가능한 패스프레이즈의 공간을 줄여 더 강하게가 아니라 살짝 약하게 만듭니다.

두 EFF 목록 모두 한 줌의 붙임표 항목을 담습니다 — t-shirt, yo-yo, drop-down, felt-tip. 구분자도 붙임표라면 그중 하나를 담은 패스프레이즈를 단어로 모호하지 않게 다시 나눌 수 없습니다. 보안이 아니라 표시 문제이고, 구분자로 공백이나 마침표를 고르면 아예 피합니다.

엔트로피가 드는 옵션과 들지 않는 것

닮은꼴 문자를 빼는 것은 강도를 가독성과 맞바꾸고, 그 맞바꿈이 보입니다. 0, O, I, l을 없애면 영숫자 문자 집합이 62개 문자에서 58개로 갑니다 — 이는 정확히 Bitcoin이 쓰는 base58 문자 집합이고, 같은 이유입니다. 각 문자가 5.95에서 5.86비트로 떨어져, 토큰이 같은 강도를 지키려면 열두 자마다 약 한 자가 더 듭니다. 사람이 화면에서 읽고 다른 데 칠 것에는 대개 그만한 값어치가 있습니다.

옵션은 그것이 뜻을 지니는 곳에만 제공됩니다. 16진수와 base64url은 인코딩이지 문자 집합이 아닙니다: 그 문자 집합은 사양으로 고정되어 있고, 0 없는 16진수는 더는 16진수가 아니라 — 아무것도 그것을 디코딩할 수 없습니다.

패스프레이즈의 각 단어 첫 글자를 대문자로 하는 것은 아무것도 더하지 않고, 여기 강도 수치는 그것을 켜도 일부러 움직이지 않습니다. 매번 적용되는 같은 변환이라 단 하나의 새 가능성도 만들지 않습니다: 구절이 대문자화됐음을 아는 공격자는 시작한 자리에 그대로 있습니다. 옵션이 있는 것은 일부 비밀번호 칸이 아직 대문자를 요구하기 때문이지 그것이 도움이 되어서가 아닙니다.

길이 고르기

기계가 다루는 것 — API 키, 세션 토큰, Webhook 시크릿, 데이터베이스 비밀번호 — 에는 아낄 이유가 없습니다. 32자 16진수나 22자 base64url이 128비트를 주고, 더 가도 설정 파일의 바이트만 듭니다.

사람이 치는 것에는 제약이 다르고 패스프레이즈가 대개 더 나은 모양입니다. 긴 목록의 여섯 단어는 열두 자 랜덤 비밀번호보다 강하고 첫 시도에 옳게 넣기가 극적으로 쉬운데, 이는 들리는 것보다 중요합니다: 사람이 잘못 치는 시크릿은 사람이 적어 두는 시크릿입니다.

숫자 코드에는 정직한 읽기가 네 자리는 13비트이고 속도 제한하지 않는 무언가에 몇 초에 소진될 수 있다는 것입니다. PIN이 안전한 것은 오직 그 둘레의 잠금 정책 때문이지 결코 제 강도 때문이 아닙니다.

자주 묻는 질문

API 키는 얼마나 길어야 하나요?
128비트 이상의 엔트로피를 노리세요. 전수 공격이 전략이기를 그치는 곳입니다. 그것은 32자 16진수, 22자 base64url, 또는 256비트를 원하면 43자 base64url입니다. 소프트웨어만 다루는 값에는 긴 쪽이 아무것도 들지 않습니다.
이것이 Math.random으로 시크릿을 생성하는 것보다 안전한가요?
네, 그리고 차이는 정도의 문제가 아닙니다. Math.random은 작은 상태를 지닌 의사 난수 생성기로, 현행 엔진이 짧은 출력의 연속에서 그것을 복원하게 하고, 그 뒤로는 그것이 낼 모든 값이 알려집니다. 이 도구는 crypto.getRandomValues, 플랫폼 CSPRNG를 쓰고, 그것은 openssl rand가 뽑는 같은 원천입니다.
왜 단일 "해독 시간"을 보이지 않나요?
그런 수가 없기 때문입니다. 같은 시크릿이 속도 제한하는 로그인 뒤에서는 닿을 수 없고 유출된 빠른 해시 뒤에서는 빨리 떨어집니다 — 11자릿수 떨어져 있습니다. 하나의 수치는 한 가정을 골라 그것을 숨겨야 하고, 읽는 이는 가정이 아니라 수를 기억합니다. 세 이름 붙은 속도가 가정을 볼 수 있는 곳에 둡니다.
패스프레이즈가 랜덤 문자열보다 약한가요?
아니요 — 강도는 얼마나 큰 목록에서 몇 단어를 뽑았는지에만 달렸고, 둘 다 보입니다. EFF 긴 목록의 여섯 단어는 약 77비트로, 열 자 랜덤 비밀번호보다 많습니다. 패스프레이즈를 약하게 만드는 것은 단어를 직접 고르는 것인데, 이것들은 그렇지 않습니다.
닮은꼴 문자를 빼야 하나요?
사람이 시크릿을 화면에서 읽고 다른 데 칠 것이면, 네: 비용이 작고 잘못 읽은 토큰은 지원 티켓입니다. 소프트웨어만 다룰 것이면 그럴 이유가 없습니다. 0, O, I, l을 없애면 문자 집합이 62개 문자에서 58개로 가는데, 이는 정확히 base58 문자 집합이고 열두 자마다 약 한 자의 길이가 듭니다.
패스프레이즈를 대문자화하면 더 강해지나요?
아니요. 매번 적용되는 같은 변경이라 패스프레이즈 공간에 단 하나의 새 가능성도 더하지 않습니다. 여기 엔트로피 수치는 그것을 켜도 그대로이고, 그것이 정확한 동작입니다. 옵션이 있는 것은 일부 비밀번호 칸이 대문자를 고집하기 때문입니다.
제가 생성한 것이 서버로 전송되나요?
아니요. 생성이 플랫폼 난수 생성기를 써서 전적으로 브라우저 안에서 돌고, 아무것도 업로드되거나 기록되지 않으며, 네트워크 연결 없이 동작합니다. 토큰은 어디에도 저장되지 않습니다 — 페이지를 새로 고치면 새 것이 나오고 옛 것은 사라집니다.