키를 생성하는 방법
- 설정하려는 대상에 맞는 프리셋을 클릭하세요. 페이지를 열면 32바이트가 선택되어 있습니다.
- 랜덤 값에서 값을 복사하세요. Laravel이나 Auth.js처럼 설정 줄이 있는 프리셋은 바로 붙여넣기에도 그 줄을 보여 줍니다.
- 다른 키가 필요하면 새로 생성을 누르세요. 개수를 늘리면 환경마다 하나씩처럼 여러 개를 한 번에 만들 수 있습니다.
프리셋은 바이트 수와 형식을 대신 정해 줍니다. 두 필드 중 하나를 바꾸면 도구가 입력한 값을 유지한 채 사용자 지정으로 돌아갑니다.
프리셋과 각 키를 쓰는 곳
| 프리셋 | 결과 | 길이 | 주로 쓰는 곳 |
|---|---|---|---|
| 16 / 32 / 64바이트 | Base64로 된 랜덤 바이트 | 24 / 44 / 88 | 범용 키, 솔트, 시크릿 |
| Laravel APP_KEY | base64: + 32바이트 | 51 | .env의 APP_KEY |
| AES-128 키 | 16바이트, Base64 | 24 | AES-128-GCM 또는 -CBC |
| AES-256 키 | 32바이트, Base64 | 44 | AES-256-GCM 또는 -CBC |
| HMAC 시크릿 | 32바이트, Base64 | 44 | HMAC-SHA256 서명, 웹훅 |
| JWT HS256 시크릿 | 32바이트, Base64URL | 43 | HS256 토큰용 JWT_SECRET |
| Auth.js 시크릿 | 32바이트, Base64 | 44 | AUTH_SECRET (이전 이름 NEXTAUTH_SECRET) |
| Django SECRET_KEY | Django 알파벳에서 뽑은 50자 | 50 | settings의 SECRET_KEY |
| Rails secret_key_base | 64바이트, hex | 128 | secret_key_base |
| API 토큰 | 32바이트, Base64URL | 43 | Bearer 토큰, 초대 링크 |
| UUID v4 (Base64URL) | 짧은 형태의 랜덤 UUID | 22 | 간결한 ID. 정식 UUID도 함께 표시 |
CSP nonce 프리셋은 용도가 다르므로 별도 페이지인 CSP nonce 생성기가 있습니다.
크기는 각 알고리즘을 따릅니다. AES 키는 정확히 16, 24, 32바이트 중 하나여야 하며 그 밖의 길이는 거부됩니다. RFC 7518은 HS256 시크릿에 최소 256비트를 요구하므로 JWT 프리셋은 32바이트를 씁니다. 해시 출력보다 짧은 HMAC 키는 HMAC을 약하게 만들기 때문에 32바이트는 HMAC-SHA256에, 64바이트 프리셋은 HMAC-SHA512에 맞습니다. Django 프리셋은 거부 샘플링으로 50자를 뽑으므로 알파벳의 모든 문자가 같은 확률로 나옵니다. Django 자체의 get_random_secret_key()와 같은 방식입니다.
Base64 키는 텍스트이고, 키는 바이트입니다
복사한 값은 랜덤 바이트를 Base64로 표현한 것입니다. 이를 사용하는 코드는 먼저 디코딩해야 합니다.
import base64, os
key = base64.b64decode(os.environ["AES_KEY"])
assert len(key) == 32
Node.js에서는 Buffer.from(process.env.AES_KEY, "base64")가 같은 일을 합니다. 44자 문자열을 그대로 AES 라이브러리에 넘기면 거부되거나(Python에서는 AESGCM key must be 128, 192, or 256 bits, Node.js에서는 Invalid key length), 느슨한 라이브러리에서는 아무 경고 없이 엉뚱한 바이트를 사용합니다. base64: 접두사를 쓰는 Laravel처럼 자기 키를 직접 읽는 프레임워크는 이 디코딩을 알아서 처리합니다.
Base64URL과 표준 Base64는 같은 바이트로 디코딩되지만, 파서는 둘 중 어느 쪽을 받을지 엄격한 경우가 많습니다. 받는 쪽이 다른 형식도 받는다는 것을 알지 못한다면 프리셋이 만든 형식을 그대로 쓰세요.
Fernet 키와 기타 형식
Python cryptography 패키지는 Fernet 키로 패딩이 있는 URL-safe Base64 형식의 32바이트, 즉 44자를 기대합니다. JWT와 API 토큰 프리셋은 =가 없는 URL-safe 형식을 만들므로 끝에 하나를 붙이거나 Python에서 생성하세요.
from cryptography.fernet import Fernet
print(Fernet.generate_key().decode())
그 밖의 경우에는 바이트 수부터 정하세요. 사용자 지정을 고르고, 라이브러리 문서에 나온 바이트 수를 입력한 뒤 Base64, Base64URL, hex 중 하나를 선택하면 됩니다. 출력 길이는 랜덤 Base64 생성기에서 설명하며, HMAC Base64나 AES 암호화에서 새 키를 바로 시험해 볼 수 있습니다.
생성한 키 관리하기
여기서 생성한 키는 복사하기 전까지 이 탭 안에만 존재합니다. 복사한 뒤에는 붙여넣은 곳만큼만 안전합니다. 운영 키는 플랫폼의 시크릿 저장소나 시크릿 관리 도구에 보관하고, 환경마다 다른 키를 쓰고, 절대 커밋하지 마세요. Git 저장소에 들어간 키는 공개된 것으로 보고 교체해야 합니다. 암호화 키를 교체하면 기존 데이터를 다시 암호화하거나 복호화용으로 이전 키를 보관해야 하므로, 운영 중인 시스템에서 APP_KEY를 바꾸기 전에 이를 미리 계획하세요.
자주 묻는 질문
32바이트 Base64 키는 어떻게 생성하나요?
페이지를 열면 32바이트 프리셋이 선택되어 있으므로 출력에 있는 키가 바로 그것입니다. =로 끝나는 44자입니다. 터미널에서는 openssl rand -base64 32가 같은 일을 합니다.
44자 Base64 문자열을 그대로 AES-256 키로 써도 되나요?
안 됩니다. AES-256에는 원시 바이트 32개가 필요하고, 44자는 그 바이트를 Base64로 적은 텍스트입니다. 먼저 문자열을 디코딩하세요. 텍스트를 그대로 넘기면 Node.js에서 “Invalid key length” 같은 오류가 납니다.
artisan 없이 Laravel APP_KEY를 만들려면 어떻게 하나요?
Laravel APP_KEY 프리셋을 선택하고 APP_KEY=base64:… 줄을 .env에 복사하세요. php artisan key:generate가 쓰는 형식과 같습니다. 즉 base64: 접두사에 기본 암호 AES-256-CBC용 랜덤 32바이트가 붙습니다.
여기서 Fernet 키를 만들 수 있나요?
Fernet 프리셋은 없습니다. 32바이트를 선택하고 형식을 Base64URL로 바꾼 뒤 43자 끝에 =를 하나 붙이세요. Fernet은 패딩이 있는 44자 URL-safe Base64를 기대하기 때문입니다. 또는 Python에서 Fernet.generate_key()를 실행하세요.
운영 환경용 키를 브라우저에서 생성해도 안전한가요?
키는 암호학적으로 안전한 생성기인 crypto.getRandomValues에서 나오고, 페이지는 이를 어디에도 보낼 수 없습니다. 더 큰 위험은 그다음 단계입니다. 키는 시크릿 관리 도구나 보호된 환경 변수에 두고, 저장소에는 절대 넣지 마세요.