Oracle
 sql >> база данни >  >> RDS >> Oracle

Oracle SQL Insert Trigger to Hash Password не работи (Проблем с CHAR)

[TL;DR] Използвайте STANDARD_HASH( RTRIM( :new.PASSWORD ), 'SHA256' ) тъй като искате да генерирате паролата на 'BruteForce ' а не 'BruteForce ' (и т.н.), подплатени с празно пространство до дължина от 64 знака (което е това, което се използва при CHAR(64) ще ви даде).

Ако не искате да използвате сол (което трябва да използвате в днешно време), тогава просто отрежете паролата с десен бутон, за да се отървете от празното пространство в края, което CHAR тип данни са допълнили низа с:

CREATE OR REPLACE TRIGGER client_hash_trigger
BEFORE INSERT ON client
FOR EACH ROW
BEGIN
  SELECT STANDARD_HASH( RTRIM( :new.PASSWORD ), 'SHA256' )
  INTO   :new.PASSWORD
  FROM   DUAL;
END;
/

След това:

CREATE TABLE client (
    id            NUMBER(10,0)
                  GENERATED ALWAYS AS IDENTITY
                  CONSTRAINT client__id__pk PRIMARY KEY,
    password      CHAR(64)
                  NOT NULL
);

INSERT INTO client (id, password) VALUES (DEFAULT, 'BruteForce');

Ще изведе:

SELECT id, password FROM client;

Хеширане и осоляване

Адаптирано от този отговор

Ако също така искате да следвате най-добрите практики, тогава трябва да солирате паролата преди хеширане:

CREATE TABLE client (
    id            NUMBER(10,0)
                  GENERATED ALWAYS AS IDENTITY
                  CONSTRAINT client__id__pk PRIMARY KEY,
    password      CHAR(64)
                  NOT NULL,
    password_salt VARCHAR2(61)
                  NOT NULL
);

Тогава вашият тригер е:

CREATE TRIGGER client_hash_trigger
BEFORE INSERT OR UPDATE ON client
FOR EACH ROW
BEGIN
  IF :new.PASSWORD = :old.PASSWORD THEN
    -- Assume things haven't changed (The chances of a hash collision are vanishingly small).
    -- Make sure the old salt is not replaced if the password hash hasn't changed.
    :new.PASSWORD_SALT := :old.PASSWORD_SALT;
  ELSE
    -- Regenerate a new salt and hash the password.
    :new.PASSWORD_SALT := DBMS_RANDOM.STRING( 'P', FLOOR( DBMS_RANDOM.VALUE( 40, 61 ) ) );
    SELECT STANDARD_HASH ( :new.PASSWORD_SALT || RTRIM( :new.PASSWORD ), 'SHA256' )
    INTO   :new.PASSWORD
    FROM   DUAL;
  END IF;
END;
/

И след това:

INSERT INTO client (id, password) VALUES (DEFAULT, 'BruteForce');

Може да изведе:

SELECT * FROM client;

db<>fiddle тук



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да сортирам асоциативен масив в PL/SQL?

  2. Изчисляване на изминалите работни часове за отворени билети (Oracle SQL)

  3. PL/SQL FOR LOOP НЕЯВЕН КУРСОР

  4. Това е в подробностите

  5. Добавяне на типове файлове, които да бъдат разпознати от Files.probeContentType(new File(.ttf).toPath());