Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle SQL Insert Trigger to Hash Password ne fonctionne pas (problème avec CHAR)

[TL;DR] Utilisez STANDARD_HASH( RTRIM( :new.PASSWORD ), 'SHA256' ) comme vous voulez générer le mot de passe sur 'BruteForce' et non 'BruteForce ' (etc.) rempli d'espaces blancs jusqu'à une longueur de 64 caractères (ce qui correspond à l'utilisation de CHAR(64) vous donnerait).

Si vous ne voulez pas utiliser de sel (que vous devriez utiliser de nos jours), coupez simplement le mot de passe pour vous débarrasser de l'espace blanc de fin que le CHAR type de données ont rempli la chaîne avec :

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

Ensuite :

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

Affichera :

SELECT id, password FROM client;

Hachage et salage

Adapté de cette réponse

Si vous souhaitez également suivre les meilleures pratiques, vous devez saler le mot de passe avant de le hacher :

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

Alors votre déclencheur est :

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

Et ensuite :

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

Peut afficher :

SELECT * FROM client;

db<>violon ici