1

Django Web サイトとアプリケーション サーバーの両方で使用される 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 のソースを見てこれを確認して、salt 生成を修正します。ただし、同じコードを使用してもチェックはとにかく失敗するValueError: Invalid saltため( で)、問題がソルトにあるのか暗号化にあるのかわかりません

PD: 必要に応じて、PBKDF2 を再実装するか、カスタム ハッシュを使用することにも同様に満足しています。

4

1 に答える 1

1

さて、ついにやります。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';
于 2012-10-05T16:28:44.603 に答える