2 ๋ถ„ ์†Œ์š”

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 ์†Œ์Šค์ฝ”๋“œ

IT๋ณด์•ˆ - PBKDF2 ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€

IT๋ณด์•ˆ - digest, ๋‹ค์ด์ œ์ŠคํŠธ ๋ž€ ๋ฌด์—‡์ธ๊ฐ€

ํƒœ๊ทธ:

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ