暗号化(Encryption)


プレイヤーが会員加入を実行すると、
{
	'user' : 'user1010',
    'password' : 'password123'
}
上記のように情報を送信DBに保存すると、
DBはハッカーに攻撃されたり、管理者がユーザーの情報を知って悪用したりします.
これらの問題を解決するには、パスワードを暗号化してデータベースに格納する必要があります.

暗号化(暗号化)


パスワード暗号化では、通常、一方向ハッシュ関数(一方向ハッシュ関数)が使用され、復号できません(暗号化>パスワード).
ハッシュ関数を使用してパスワードを暗号化メッセージの要約に変換する方法.
たとえばhash 256という名前の関数を使用します.
>>> import hashlib
>>>
>>> a = hashlib.sha256()
>>> a.update(b'a')
>>> a.hexdigest()
'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb'
>>>
>>> b = hashlib.sha256()
>>> b.update(b'ab')
>>> b.hexdigest()
'fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603'
'a''ab'をバイナリに変換し,hash 256ハッシュ関数により変換すると,両者の間に大きな差があることがわかる.
しかし、この方法では、ハッシュ値をあらかじめ計算した「Rainbow table」を用いることもできる.
任意の文字列の値をハッシュ関数に代入して生成した要約をハッカー攻撃されたオブジェクトの要約と比較することで,ハッカー攻撃を完全に行うことができる.
これらの問題を解決するために、bcryptによる保存および鍵の引張りにより、セキュリティを強化することができる.

Saltingとは?既存のパスワードに任意の文字列を追加します.
KeyStretchingは、再入力されたハッシュ結果を使用してハッシュを繰り返します.
例えば、ハッシュがsha 256の場合、
'a' + 'salt'
=> 1978080463c89468c84aeb4c135be4b65a7961153897cf90dda025e3536f1c56
=> 3c412bef7d8d84bbeaf72df4498b27447d589457a1532888dbdf11edada623b2
=> 4cce89fa5bdbdd638d357145fecda5d51a256289ea810f0b8df31c0d90bf561a
...
同じように繰り返します.△この繰り返し回数は非常に多い.views.pyを既存のパスワードに適用すると
import bcrypt

...
class SignUpView(View):
    def post(self, request):
        data = json.loads(request.body)
        
        try:
            ...
            hashed_password = bcrypt.hashpw(data['password'].encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
            # 먼저 받아온 password를 encode하고 bcrypt 처리한 다음, 다시 decode

            User.objects.create(
                name         = data['name'],
                email        = data['email'],
                password     = hashed_password,
                phone_number = data['phone_number'],
                age          = data['age'],
                gender       = data['gender'],
                birth_date   = data['birth_date']
            )
上にbcryptで暗号化されたパスワードは、復号してDBに保存する必要があります.
decodeの理由は、データベースがstrの形式で格納されているからです.
class LoginView(View):
    def post(self, request):
        data = json.loads(request.body)

        try:
            if not User.objects.filter(email=data['email']).exists():
                return JsonResponse({"MESSAGE":"INVALID_USER"}, status=401)
            
            user = User.objects.get(email=data['email'])

            check_password = bcrypt.checkpw(data['password'].encode('utf-8'), user.password.encode('utf-8'))
            #받아온 password를 encode하고, DB내 password를 꺼내와 encode하고 실행
            
            if not check_password:
                return JsonResponse({"MESSAGE":"INVALID_USER"}, status=401)
	    return JsonResponse({"MESSAGE":"SUCCESS"}, status=200) 
user.password DBにロードされたパスワードが再符号化されてこそ、bcrypt.checkpw()が正常に動作します.
リファレンス
( https://snippets-save-us.tistory.com/44 )