https://www.postgresql.org/docs/current/pgcrypto.html | pgcrypto
I har nok alle prøvet at bygge et sikkert loginsystem som gør brug af hashing, salt og måske endda peber! På tidligere hovedforløb bruger vi ofte en pakke kaldet BCrypt i C# som hjælper os med implementeringen, men vidste I at Postgres :postgres: faktisk har et modul som kan gøre det for os? Lad os tage et kig på hvordan vi gør!
CREATE EXTENSION IF NOT EXISTS pgcrypto;
Når du skal gemme et password, skal du bruge to funktioner: crypt()
og gen_salt()
.
Eksempel på at gemme et password med Blowfish (bf), der minder om BCrypt:
INSERT INTO users (username, password_hash)
VALUES ('Mathias', crypt('hemmeligtPassword', gen_salt('bf')));
Her genereres en tilfældig "salt", og passwordet hashes med Blowfish-algoritmen, der svarer til BCrypt.
For at kontrollere, om et indtastet password matcher det gemte hash, bruger man igen funktionen crypt()
. Man bruger det tidligere gemte hash som salt, og sammenligner resultatet med det originale hash.
Eksempel på verifikation:
SELECT password_hash = crypt('indtastetPassword', password_hash) AS er_match
FROM users
WHERE username = 'Mathias';
Dette returnerer true
, hvis passwordet er korrekt, og false
, hvis det ikke er.
Blowfish-algoritmen (bf
) understøtter iterationer, som gør hash-funktionen langsommere og dermed sværere at brute-force. Standard er 6 iterationer, men man kan hæve dette tal for at øge sikkerheden (maks. 31):
INSERT INTO users (username, password_hash)
VALUES ('Mathias', crypt('hemmeligtPassword', gen_salt('bf', 10)));
bf
(Blowfish), der er adaptiv og langsom.md5
eller des
.I C# bruger du typisk en metode som:
string hashedPassword = BCrypt.Net.BCrypt.HashPassword(password);
bool isMatch = BCrypt.Net.BCrypt.Verify(inputPassword, hashedPassword);
I PostgreSQL med pgcrypto er princippet det samme:
gen_salt('bf')
svarer til at generere en salt i BCrypt.crypt(password, salt)
svarer til at generere og verificere et hash.Ofte laver vi krypteringslogikken på vores backend og det giver faktisk ret god mening, men lad os lige se på nogle fordele og ulemper ved at gøre det på database niveau i stedet!
Fordele:
Ulemper: