Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle SQL Insert Trigger to Hash Password funktioniert nicht (Problem mit CHAR)

[TL;DR] Verwenden Sie STANDARD_HASH( RTRIM( :new.PASSWORD ), 'SHA256' ) wie Sie das Passwort auf 'BruteForce' generieren möchten und nicht 'BruteForce ' (usw.) mit Leerzeichen auf eine Länge von 64 Zeichen aufgefüllt (was mit CHAR(64) erreicht wird würde dir geben).

Wenn Sie kein Salt verwenden möchten (was Sie heutzutage verwenden sollten), dann kürzen Sie einfach das Passwort nach rechts, um das abschließende Leerzeichen zu entfernen, das den CHAR enthält Datentyp haben den String aufgefüllt mit:

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

Dann:

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

Wird ausgegeben:

SELECT id, password FROM client;

Hashing und Salting

Angepasst von dieser Antwort

Wenn Sie auch den Best Practices folgen möchten, sollten Sie das Passwort vor dem Hashing salzen:

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

Dann ist Ihr Trigger:

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

Und dann:

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

Kann ausgeben:

SELECT * FROM client;

db<>fiddle hier