with vincent custom contrib auth and django authentication passwords

vincent - request.user django



Hacer que Django.contrib.auth almacene la contraseƱa de texto sin formato (4)

¿Por qué?

Tratar de hacer que un marco de calidad como Django haga algo incorrecto , a propósito, puede requerir cierta cantidad de tirones de cabello.

Tengo un sitio basado en Django (aún no se ha iniciado, por lo que no hay usuarios reales) que use django.contrib.auth , y quiero almacenar contraseñas como hashes SHA-1 de texto plano, no salados.

La pregunta es, ¿cuál es el mejor enfoque para hacer esto, con suerte, sin parchear (o parche de monos) el código fuente de Django?

NOTA : Sé perfectamente que esto es ciertamente menos seguro. Se requiere texto sin formato para realizar la autenticación de respuesta al desafío, como CHAP para PPTP VPN, DIGEST-MD5 para IMAP4 y HTTP Digest para almacenamiento de archivos basado en WebDAV. Por lo tanto, estoy cambiando la seguridad de nivel de base de datos con seguridad de nivel de conexión.

Por supuesto, estoy considerando educar y alentar a los usuarios a usar certificados X.509 (y no tener contraseñas), pero esto no es tan fácil.

Encriptar (enmascarar) contraseñas de manera reversible y usar algunos permisos de nivel de columna para que la contraseña sea INSERTable / UPDATEable, pero no seleccionable por el usuario web (solo accesible para alguna función de verificación personalizada, como SELECT * FROM users WHERE ''somesha1hash'' = USER_HMAC(id, ''salt'') ) por lo que las contraseñas no serán "justo allí" es una buena idea y trataré de hacerlo. Las sugerencias para proteger los datos de texto sin formato son muy bien recibidas, pero lo que más deseo escuchar es cómo hackear la forma en que se almacenan las contraseñas.


En Django, no es tan difícil: simplemente tiene que escribir un servidor de autenticación , que autenticará a los usuarios contra la contraseña almacenada en texto sin formato.

Dicho esto, nunca debe almacenar contraseñas en texto sin formato .
El punto principal es que las personas tienden a usar la misma contraseña una y otra vez y, por lo tanto, al utilizar texto sin formato en su sitio, pone a sus usuarios en riesgo de que un atacante acceda a su cuenta bancaria.
Jeff Atwood escribió una buena publicación sobre este tema, Probablemente está almacenando contraseñas incorrectamente ; Sugiero que lo leas, porque explicará los problemas del texto sin formato en las contraseñas de una manera mucho mejor que yo.
Al menos, debe alentar a sus usuarios a usar una contraseña diferente de las "seguras"; por ejemplo, simplemente podría generar nuevas contraseñas aleatorias, incluso si este enfoque tiene sus propias limitaciones, también.

Otro enfoque, que podría ser mucho más seguro: escriba su backend de autenticación, que se validará contra (por ejemplo) el almacenamiento de WebDAV. No almacena las contraseñas en ningún lugar de su sistema, simplemente las pasa. No sé si puede funcionar en su caso (especialmente si tiene que autenticarse contra varias fuentes) pero al menos puede intentarlo.


No hagas esto Viola los principios básicos de seguridad. Mejor no tener contraseña en absoluto que hacer esto.

Con respecto a su pregunta actualizada: almacene esas contraseñas de acceso externo encriptadas en una tabla separada (de todos modos, pueden no ser todas iguales). Contraseña de usuario del usuario para la clave salada generada para este cifrado. Luego, cuando ella inicia sesión, su aplicación puede descifrar y usar esas claves.

Esto realmente difícil de hacer bien. ¡Buena suerte!


Hay un montón de escenarios perfectamente buenos para mantener las contraseñas en texto sin formato (sitios de juegos para niños, etc.). En realidad es bastante fácil de hacer.

En su configuración, agregue:

PASSWORD_HASHERS = (''wereallfriendsinunikittyland.PlainTextPassword'',)

wereallfriendsinunikittyland.py crear un archivo wereallfriendsinunikittyland.py .

from django.contrib.auth.hashers import BasePasswordHasher class PlainTextPassword(BasePasswordHasher): algorithm = "plain" def salt(self): return '''' def encode(self, password, salt): assert salt == '''' return password def verify(self, password, encoded): return password == encoded def safe_summary(self, encoded): return OrderedDict([ (_(''algorithm''), self.algorithm), (_(''hash''), encoded), ])