sql >> Base de Datos >  >> RDS >> Oracle

Oracle SQL Insert Trigger to Hash Password no funciona (problema con CHAR)

[TL;DR] Use STANDARD_HASH( RTRIM( :new.PASSWORD ), 'SHA256' ) como desea generar la contraseña en 'BruteForce ' y no 'BruteForce ' (etc.) rellenado con espacios en blanco hasta una longitud de 64 caracteres (que es lo que usa CHAR(64) te daría).

Si no desea usar un salt (que debería usar en este día y edad), simplemente recorte la contraseña a la derecha para deshacerse del espacio en blanco final que el CHAR el tipo de datos ha rellenado la cadena con:

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

Entonces:

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

Dará salida:

SELECT id, password FROM client;

Hashing y Salado

Adaptado de esta respuesta

Si también desea seguir las mejores prácticas, debe saltear la contraseña antes de aplicar el algoritmo hash:

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

Entonces tu disparador es:

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

Y luego:

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

Salida de mayo:

SELECT * FROM client;

db<>fiddle aquí