๐[Django] ๋น๋ฐ๋ฒํธ ํด์ฑ ํจ์?
Django์๋ ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํ ํด์ฃผ๋ ๋ด์ฅ ํจ์๊ฐ ์๋ค!
์ฐ์ ๋ด๊ฐ ์ฌ์ฉ ๊ฒฝํ์ด ์๋ make_password()
์ ๋ํด ์ ๋ฆฌํ๋ค!
make_password()
๋ django์์ ์ ๊ณตํ๋ ๋ด์ฅ ํจ์๋ก, django์์ ์ง์ํ๋ ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด์ ๋ฌธ์์ด์ ์ํธํ ํ๋ ํจ์๋ค.
from django.contrib.auth.hashers import make_password
์ ์ ์ธ ํ ์ฌ์ฉํ ์ ์๋ค.
from django.contrib.auth.hashers import make_password
hashed_password = make_password(password)
์ด๋ฐ ์์ผ๋ก password
๋ผ๋ ๋ฌธ์์ด์ make_password()
์ ์ ๋ฌํ๋ฉด ์ํธํ๋ ๋ฌธ์์ด๋ก ๋ณํ๋์ด hashed_password
์ ์ ์ฅ๋๋ค.
make_password() ์ฝ๋
def make_password(password, salt=None, hasher="default"):
"""
Turn a plain-text password into a hash for database storage
Same as encode() but generate a new random salt. If password is None then
return a concatenation of UNUSABLE_PASSWORD_PREFIX and a random string,
which disallows logins. Additional random string reduces chances of gaining
access to staff or superuser accounts. See ticket #20079 for more info.
"""
if password is None:
return UNUSABLE_PASSWORD_PREFIX + get_random_string(
UNUSABLE_PASSWORD_SUFFIX_LENGTH
)
if not isinstance(password, (bytes, str)):
raise TypeError(
"Password must be a string or bytes, got %s." % type(password).__qualname__
)
hasher = get_hasher(hasher)
salt = salt or hasher.salt()
return hasher.encode(password, salt)
๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํ ํ๋ฉด, ๋ก๊ทธ์ธ์ ํ ๋, ์ด๋ป๊ฒ ๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํ ๊น?
์ด๊ฑด check_password()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ํด๊ฒฐํ ์ ์๋ค!
์ด ๋ฉ์๋ ๋ํ from django.contrib.auth.hashers import check_password
๋ฅผ ์ ์ธ ํ ์ฌ์ฉํ ์ ์๋ค!
make_password()๋ ์ด๋ค ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ ๊น?
๊ธฐ๋ฅ ๊ตฌํ์ ์ํด ๊ธํ๋๋ก make_password()
๋ฅผ ์ฌ์ฉํ๋๋ฐ, ์ต๊ทผ์ ์ด ๋ฉ์๋๋ ์ด๋ค ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ ๊น?๋ผ๋ ์๊ฐ์ด ๋ค์๋ค.
์ด๋ค ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋์ง๋ django์ ๊ณต์ ๋ฌธ์์์ ํ์ธํ ์ ์์๋ค.
[๊ณต์ ๋ฌธ์ ๋ฐ์ท]
[์์ด]
make_password(password, salt=None, hasher='default')ยถ
Creates a hashed password in the format used by this application.
It takes one mandatory argument: the password in plain-text (string or bytes).
Optionally, you can provide a salt and a hashing algorithm to use, if you donโt want to use the defaults (first entry of PASSWORD_HASHERS setting).
See **Included hashers** for the algorithm name of each hasher.
If the password argument is None, an unusable password is returned (one that will never be accepted by check_password()).
[ํ๊ตญ์ด]
make_password( ๋น๋ฐ๋ฒํธ , ์๊ธ = ์์ , ํด์ = '๊ธฐ๋ณธ๊ฐ' ) ยถ
์ด ์ ํ๋ฆฌ์ผ์ด์
์์ ์ฌ์ฉํ๋ ํ์์ผ๋ก ํด์๋ ๋น๋ฐ๋ฒํธ๋ฅผ ์์ฑํฉ๋๋ค.
ํ๋์ ํ์ ์ธ์, ์ฆ ์ผ๋ฐ ํ
์คํธ(๋ฌธ์์ด ๋๋ ๋ฐ์ดํธ)์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ ํ์ ์ผ๋ก ๊ธฐ๋ณธ๊ฐ(PASSWORD_HASHERS ์ค์ ์ ์ฒซ ๋ฒ์งธ ํญ๋ชฉ) ์ ์ฌ์ฉํ์ง ์์ผ๋ ค๋ ๊ฒฝ์ฐ ์ฌ์ฉํ ์ํธ ๋ฐ ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
๊ฐ ํด์์ ์๊ณ ๋ฆฌ์ฆ ์ด๋ฆ์ **ํฌํจ๋ ํด์**๋ฅผ ์ฐธ์กฐํ์ธ์.
๋น๋ฐ๋ฒํธ ์ธ์๊ฐ ์ด๋ฉด None์ฌ์ฉํ ์ ์๋ ๋น๋ฐ๋ฒํธ๊ฐ ๋ฐํ๋ฉ๋๋ค( ์์๋ ์ ๋ ํ์ฉ๋์ง ์๋ ๋น๋ฐ๋ฒํธ check_password()).
์ฌ๊ธฐ์ Included hashers
๋ ๋ค์๊ณผ ๊ฐ์๋ค.
The corresponding algorithm names are:
- pbkdf2_sha256
- pbkdf2_sha1
- argon2
- bcrypt_sha256
- bcrypt
- scrypt
- md5
์ด ์ค default
์๊ณ ๋ฆฌ์ฆ์ pbkdf2_sha256
์๊ณ ๋ฆฌ์ฆ์ด๋ค!
์ฆ, make_password()
๋ pbkdf2_sha256
์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ ๋ฉ์๋๋ผ๋ ๊ฒ์ ์ ์ ์์๋ค!
pbkdf2_sha256 ์๊ณ ๋ฆฌ์ฆ?
์ฐ์ pbkdf2
๋, Password-Based Key Derivation Function Version 2
์ ์ฝ์๋ค.
์ฌ์ฉ์์ ํจ์ค์๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํค(key)๋ฅผ ์ ๋ํ๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ โ ๋ฏธ๊ตญ์ NIST์์ ๊ถ์ฅํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ผ๊ณ ํ๋ค.
์ด๋ ์ฌ์ฉ์์ ํจ์ค์๋์ ํด์ํจ์
, Salt
, ๋ฐ๋ณตํ์(iteration)
๋ฑ์ ์ง์ ํ์ฌ ํจ์ค์๋์ ๋ํ ๋ค์ด์ ์คํธ(Digest)
๋ฅผ ์์ฑํ๋ค.
- ๋ค์ด์ ์คํธ(Digest): ์ ์ฒด ๋ฉ์์ง๋ฅผ ํด์ํจ์์ ๋ฃ์ด ์ฐ์ฐ ํ ์์ฑ๋ ์์ ๊ฐ
- ๊ณ์ฐ์ด ๋น ๋ฆ
- ๋น๊ฐ์ญ์ : โ๋๋๋ฆด ์ ์๋โ
- ์์ธก ๋ถ๊ฐ๋ฅ
์ฐธ๊ณ ์๋ฃ
[Password management in Django | Django documentation](https://docs.djangoproject.com/en/5.0/topics/auth/passwords/#django.contrib.auth.hashers.make_password) |
make_password() github ์์ค์ฝ๋
๋๊ธ๋จ๊ธฐ๊ธฐ