2012-10-04 42 views
0

的BCryptPasswordHasher Django的我有一个Postgres是被两个Django的网站和应用程序服务器的9.1数据库。如何重新实现在Postgres 9.1

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

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的无法与登陆):

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身份验证系统都工作正常,所以我不知道我很想念......

之前,我有这样的:

-- 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: Invalid salt),所以我不知道问题出在盐中还是加密

PD:我会同样满意于重新实现PBKDF2或使用自定义散列器,如果necesary

+0

“无效的盐”是指东西,*使用它作为输入*不喜欢它..错误的类型?不正确的值? (也就是说,有什么价值,什么做的文件说是必需的?) – 2012-10-04 21:51:29

+0

是的,我明白。仅仅表明以前的实现不兼容...... – mamcx

+0

从安全角度来看,这是一个坏主意。明文密码应该尽可能少地传递。尽可能早地在django中做哈希,然后丢弃明文密码。当您发送明文密码数据库,您有有关保护数据库连接的担心(你应该担心这个反正),确保密码不会在查询记录显示,等,等,最好避免额外的风险。 – Mark

回答

0

好了,终于我做到这一点。我通过postgres和django检查生成的字符串,并发现用postgres复制盐。所以是一个简单的变化:

-- 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';