如何用postgres重新实现django的BCryptPasswordHasher 9.1 [英] How reimplement BCryptPasswordHasher of django with postgres 9.1

查看:154
本文介绍了如何用postgres重新实现django的BCryptPasswordHasher 9.1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Postgres 9.1数据库,由django网站和应用程序服务器使用。

I have a postgres 9.1 database that is used by both a django website and a application server.

目前,我在两个系统中使用旧的SHA1身份验证,但是将升级到bcrypt。我有这个:

Currently, I use the old SHA1 authentication in both system, but will upgrade to bcrypt. I have this:

CREATE OR REPLACE FUNCTION random_string(length INTEGER, OUT RETURNS TEXT) 
AS $$
BEGIN
  IF length < 0 THEN
    raise exception 'Given length cannot be less than 0';
  END IF;

  RETURNS = libs.gen_salt('bf', length);
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION encryp_TEXT(_TEXT TEXT, OUT RETURNS TEXT)
AS $$
DECLARE
    hash TEXT := '';
    salt TEXT := '';
BEGIN
    salt := random_string(12);
    hash := libs.crypt(_TEXT,salt);

    RETURNS =  'bcrypt$' || salt || '$' || hash;
END;
$$
LANGUAGE 'plpgsql';

select encryp_TEXT('123');

但是,生成无效的密码(即django无法登录):

However, is generating invalid passwords (ie, django can't login with that):

In [9]: from django.contrib.auth.hashers import BCryptPasswordHasher

In [10]: a=BCryptPasswordHasher()

In [19]: p='bcrypt$$2a$12$dCw4N7U1aQbuTVhE8ybV0O$2a$12$dCw4N7U1aQbuTVhE8ybV0OVVeFYgl1EMtBhG.4/PobMWDlih1IGLK'

In [20]: a.verify('123',p)
Out[20]: False

之前,使用SHA1认证两个系统工作正常,所以我不知道我是什么失踪...

Before, using the SHA1 auth both system work fine, so I wonder what I'm missing...

在我有这个之前:

-- Genera una cadena aleatoria del tamaño especificado
CREATE OR REPLACE FUNCTION random_string(length INTEGER, OUT RETURNS TEXT) 
AS $$
DECLARE
  chars TEXT[] := '{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}';
  result TEXT := '';
  i INTEGER := 0;
BEGIN
  IF length < 0 THEN
    raise exception 'Given length cannot be less than 0';
  END IF;

  FOR i IN 1..length LOOP
    result := result || chars[1+random()*(array_length(chars, 1)-1)];
  END LOOP;

  RETURNS =  result;
END;
$$
LANGUAGE plpgsql;

-- Encripta con SHA1 una cadena y retorna el tipo de algoritmo + salt + hash
CREATE OR REPLACE FUNCTION encryp_TEXT(_TEXT TEXT, OUT RETURNS TEXT)
AS $$
DECLARE
    hash TEXT := '';
    salt TEXT := '';
BEGIN
    salt := random_string(12);
    hash := encode( libs.digest(salt || _TEXT, 'sha1'), 'hex');

    RETURNS =  'sha1$' || salt || '$' || hash;
END;
$$
LANGUAGE 'plpgsql';

查看django的源码并检查这个,我修改了盐的生成。但是,即使我使用相同的代码,检查也会失败(使用 ValueError:无效盐),所以我不知道问题是在盐或加密

Looking at the source of django and checking this, I modify the salt generation. However, even if I use the same code the check will fail anyway (with a ValueError: Invalid salt), so I don't know if the problem is in the salt or the encrypt

PD:对于重新实现PBKDF2或使用自定义哈希值,我将会同样高兴,如果有必要

P.D: I will be equally happy with reimplement PBKDF2 or using a custom hasher, if necesary

推荐答案

嗯,最后我这样做。我通过postgres和django检查生成的字符串,发现那些用postgres复制的字符串复制了salt。所以简单的改变:

Well, finally I do it. I check the generated string by postgres and django and found that the ones with postgres duplicate the salt. So was a simple change to:

-- Encripta con bcrypto una cadena y retorna el tipo de algoritmo + salt + hash, django compatible
CREATE OR REPLACE FUNCTION encryp_text(_TEXT TEXT, OUT RETURNS TEXT)
AS $$
DECLARE
    hash TEXT := '';
    salt TEXT := '';
BEGIN
    salt := random_string(12);
    hash := libs.crypt(_TEXT,salt);

    RETURNS =  'bcrypt$' || hash;
END;
$$
LANGUAGE 'plpgsql';

这篇关于如何用postgres重新实现django的BCryptPasswordHasher 9.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆