sql >> Databáze >  >> RDS >> Oracle

Oracle SQL Insert Trigger to hash Password nefunguje (problém s CHAR)

[TL;DR] Použijte STANDARD_HASH( RTRIM( :new.PASSWORD ), 'SHA256' ) jak chcete vygenerovat heslo na 'BruteForce' a ne 'BruteForce ' (atd.) doplněno mezerami o délce 64 znaků (což je použití CHAR(64) by vám dal).

Pokud nechcete používat sůl (kterou byste měli používat v dnešní době), pak stačí oříznout heslo, abyste se zbavili mezery na konci, kterou CHAR datový typ doplnili řetězec o:

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

Potom:

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

Bude výstup:

SELECT id, password FROM client;

Hašování a solení

Převzato z této odpovědi

Pokud se také chcete řídit osvědčenými postupy, měli byste heslo před hashováním osolit:

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

Pak je váš spouštěč:

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

A pak:

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

Květen výstup:

SELECT * FROM client;

db<>fiddle zde



  1. R:seznam řetězců v ifelse

  2. Sequelize, MySQL - Filtrování řádků v tabulce s hodnotami sloupců JSON

  3. SELECT / GROUP BY - časové úseky (10 sekund, 30 sekund atd.)

  4. SQLiteException žádná taková tabulka:ItemTable při kompilaci:Select_id,.... z ItemTable