Nano Hash - криптовалюты, майнинг, программирование

Поле пароля в модели Django

Я пытаюсь создать модель, в которой я могу хранить имена пользователей и пароли для других приложений. Как я могу установить поле пароля в Django, чтобы оно не было в виде простого текста в админке? Заранее спасибо.


  • Спасибо всем за ваши ответы. Я придерживаюсь предложения Млисснера и Маноджа, хотя особое внимание уделяется ребусу, поскольку его подход подходит для простых приложений, где вам просто нужна простая функциональность без особой безопасности. 16.09.2010
  • Это может сделать то, что вы хотите. djangosnippets.org/snippets/1330 03.12.2012
  • Пинг - Вы реализовали это? Я смотрю на реализацию подобной вещи, но я не уверен, с чего начать, не могли бы вы указать мне правильное направление? 27.11.2013
  • Джек - есть, но я сделал немного по-другому. Я использую set_password, как Маной указал в своем ответе, оттуда я могу проверить хэш пароля, введенного пользователем для входа в систему, либо путем разделения строки algo/salt/hash, оставив только хеш для сравнения, либо используя статическую соль и сравните их вообще. 28.11.2013

Ответы:


1

Как @mlissner предложил, модель auth.User - хорошее место для поиска. Если вы проверите исходный код, вы см., что поле password является CharField.

password = models.CharField(_('password'), max_length=128, help_text=_("Use 
'[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))

Модель User также имеет метод set_password.

def set_password(self, raw_password):
    import random
    algo = 'sha1'
    salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
    hsh = get_hexdigest(algo, salt, raw_password)
    self.password = '%s$%s$%s' % (algo, salt, hsh)

Вы можете извлечь некоторые подсказки из этого метода о создании пароля и его сохранении.

15.09.2010
  • Итак, если бы я реализовал аналогичный метод, как бы я затем дехэшировал пароль, когда мне нужно было использовать его для аутентификации с помощью API, такого как Facebook? 05.10.2011
  • Как Марк ответил ниже, вы не можете. Но вы можете хэшировать введенный пользователем пароль, используя тот же алгоритм и соль, и проверить, что значение равно тому, которое вы сохранили в своей базе данных. 11.12.2012
  • Привет, ссылка на исходный код ведет к 404, не могли бы вы предоставить исправленную ссылку 05.02.2016
  • Django изменился много с тех пор, как был опубликован этот ответ, чтобы разрешить переопределение и изменение модели пользователя, но суть по-прежнему верна. Тяжелые части для новой настройки AbstractBaseUser и проверки паролей находятся в django.contrib.auth.hashers. Опять же, хотя проза этого ответа в целом верна, код устарел. Ответ мог бы сделать с некоторым тщательным переписыванием. 13.12.2016

  • 2

    Я не думаю, что вы когда-нибудь сможете расшифровать зашифрованный пароль, который был сохранен способом, аналогичным обычным паролям пользователя django. Частью безопасности является то, что они не дехэшируются.

    27.12.2011

    3

    К сожалению, на этот вопрос нет простого ответа, потому что это зависит от приложений, в которых вы пытаетесь пройти аутентификацию, а также от того, насколько безопасными должны быть поля пароля.

    Если ваше приложение Django будет использовать пароль для аутентификации в другом приложении, которое требует отправки открытого пароля, то ваши варианты:

    • Сохраните пароль в виде обычного текста в вашей модели Django (ваш вопрос подразумевает, что вы не хотите этого делать)
    • Захват мастер-пароля от пользователя, прежде чем он сможет разблокировать сохраненный пароль для других приложений
    • Замаскируйте пароль в модели, чтобы к нему мог получить доступ любой, у кого есть права доступа к необработанному хранилищу данных, но он просто не очевиден для случайных зрителей.

    Вы можете использовать пароль пользователя Django в качестве главного пароля, если используете встроенную пользовательскую модель Django. Это означает, что вам нужно будет хранить этот мастер-пароль в памяти, что может затруднить некоторые операции, такие как перезапуск сервера или запуск резервных серверов с балансировкой нагрузки.

    Альтернатива хранению паролей

    К счастью, многие современные приложения поддерживают это по-другому, используя систему токенов доступа, основанную на ключе, а не на пароле. Пользователей сопровождают в процессе установки связи между двумя приложениями, а за кулисами приложения генерируют ключи для аутентификации друг друга либо на постоянной основе, либо с определенной датой истечения срока действия.

    Facebook, например, поддерживает эту модель, и у них есть обширная документация о том, как она работает:

    Разработчики Facebook: токены и типы доступа

    После того, как вам удалось установить связь с Facebook с помощью [OAuth 2.0] (http://tools.ietf.org/html/draft-ietf-oauth-v2-12), вам, вероятно, будет проще добавлять ссылки на другие приложения с помощью этого тот же протокол.

    16.11.2012

    4

    Лучше всего (я знаю) покопаться в коде в коде django и посмотреть, как это делается там. Насколько я помню, они генерируют хэш с солью, так что простые текстовые значения никогда и нигде не хранятся, а хранятся хеш и соль.

    Если вы зайдете в установку django и поищите такие слова, как хеш и соль, вы должны найти это довольно быстро. Извините за расплывчатый ответ, но, возможно, он направит вас на правильный путь.

    15.09.2010

    5

    Если вам нужно обратимое поле пароля, вы можете использовать что-то вроде этого:

    from django.db import models
    from django.core.exceptions import ValidationError
    from django.conf import settings
    
    from os import urandom
    from base64 import b64encode, b64decode
    from Crypto.Cipher import ARC4
    from django import forms
    
    
    
    PREFIX = u'\u2620'
    
    
    class EncryptedCharField(models.CharField): 
        __metaclass__ = models.SubfieldBase
    
        SALT_SIZE = 8
    
        def __init__(self, *args, **kwargs):
            self.widget = forms.TextInput       
            super(EncryptedCharField, self).__init__(*args, **kwargs)
    
        def get_internal_type(self):
            return 'TextField'    
    
        def to_python(self, value):
            if not value:
                return None
            if isinstance(value, basestring):
                if value.startswith(PREFIX):
                    return self.decrypt(value)
                else:
                    return value
            else:
                raise ValidationError(u'Failed to encrypt %s.' % value)
    
        def get_db_prep_value(self, value, connection, prepared=False):
            return self.encrypt(value)        
    
        def value_to_string(self, instance):
            encriptado = getattr(instance, self.name)
            return self.decrypt(encriptado) if encriptado else None
    
        @staticmethod
        def encrypt(plaintext):
            plaintext = unicode(plaintext)
            salt = urandom(EncryptedCharField.SALT_SIZE)
            arc4 = ARC4.new(salt + settings.SECRET_KEY)
            plaintext = u"%3d%s%s" % (len(plaintext), plaintext, b64encode(urandom(256-len(plaintext))))
            return PREFIX + u"%s$%s" % (b64encode(salt), b64encode(arc4.encrypt(plaintext.encode('utf-8-sig'))))
    
        @staticmethod
        def decrypt(ciphertext):
            salt, ciphertext = map(b64decode, ciphertext[1:].split('$'))
            arc4 = ARC4.new(salt + settings.SECRET_KEY)
            plaintext = arc4.decrypt(ciphertext).decode('utf-8-sig')
            return plaintext[3:3+int(plaintext[:3].strip())]
    

    Часть шифрования основана на фрагменте на https://djangosnippets.org/snippets/1330/. , я просто превратил его в модель поля, добавил поддержку utf-8 и добавил префикс в качестве обходного пути для глупое использование Django функции to_python()

    21.05.2014
  • Чтобы использовать вышеизложенное, вы, вероятно, захотите pip install pycrypto, а не pip install Crypto. Кроме того, теперь в pypi доступен пакет со многими полями, который называется django-encrypted-fields (или для python 3, django-encrypted-fields-python3). 17.02.2018
  • Весь смысл хэша в том, чтобы быть необратимым! Ни у кого не должно быть возможности получить доступ к исходному паролю. plaintextoffenders.com/faq/devs 23.11.2018
  • Да, это правда, и если вы можете решить проблему с помощью хеша, вы обязательно должны его использовать. Но иногда вам может понадобиться получить пароль: представьте, например, что вашей программе необходимо войти на сторонний сервер, а пароль для доступа к этому стороннему серверу находится в вашей базе данных. 23.11.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..