funcool

A channel for discussing and asking questions about Funcool libraries https://github.com/funcool/
Yehonathan Sharvit 2017-03-02T13:52:49.000605Z

@niwinz I have a question regarding buddy-hashers

niwinz 2017-03-02T13:53:04.000606Z

tell me 😄

Yehonathan Sharvit 2017-03-02T13:53:16.000607Z

I’d like to encrypt passwords in a consistent way

Yehonathan Sharvit 2017-03-02T13:53:38.000608Z

I mean encrypting the same password should give the same result

Yehonathan Sharvit 2017-03-02T13:53:49.000609Z

I tried to play with hashers/derive

Yehonathan Sharvit 2017-03-02T13:54:10.000611Z

But the problem is that the :salt is implicit

niwinz 2017-03-02T13:54:17.000612Z

hmm

niwinz 2017-03-02T13:55:09.000613Z

I think just passing fixed salt should work

niwinz 2017-03-02T13:55:12.000614Z

let me try it...

Yehonathan Sharvit 2017-03-02T13:55:35.000615Z

Probalby, but how do I generate a good salt?

Yehonathan Sharvit 2017-03-02T13:55:58.000616Z

I need to use (nonce/random-bytes 8)?

niwinz 2017-03-02T13:59:25.000617Z

user=> (def salt (nonce/random-bytes 16))
#'user/salt
user=> (hs/derive "foo" {:salt salt})
"bcrypt+sha512$a19816aad5a6dea6c3d927a0fbca8e75$12$c679579c550318d9294c562540526860fc6e8877c7870f85"
user=> (hs/derive "foo" {:salt salt})
"bcrypt+sha512$a19816aad5a6dea6c3d927a0fbca8e75$12$c679579c550318d9294c562540526860fc6e8877c7870f85"
user=> (hs/derive "foo" {:salt salt})
"bcrypt+sha512$a19816aad5a6dea6c3d927a0fbca8e75$12$c679579c550318d9294c562540526860fc6e8877c7870f85"

niwinz 2017-03-02T13:59:31.000618Z

seems to work

niwinz 2017-03-02T13:59:49.000619Z

the salt size depends on the final algorithm

niwinz 2017-03-02T14:00:04.000620Z

for default bcrypt you need 16 bytes (or 128 bits) salt

niwinz 2017-03-02T14:00:40.000621Z

if you don't provide a salt, a randomly one is generated

niwinz 2017-03-02T14:00:50.000622Z

of the size approriate for the chosen algorithm

Yehonathan Sharvit 2017-03-02T14:00:59.000623Z

How do I serialize the salt?

Yehonathan Sharvit 2017-03-02T14:02:31.000624Z

I mean I don’t want to generate a new salt each time my app loads...

niwinz 2017-03-02T14:02:53.000625Z

The question here is why you want a fixed salt?

niwinz 2017-03-02T14:03:11.000626Z

it decreases the security of the derived password

Yehonathan Sharvit 2017-03-02T14:03:32.000627Z

Oh. Maybe I’m missing something (I’m not a security expert)

Yehonathan Sharvit 2017-03-02T14:03:44.000628Z

I don’t want to store plain passwords in the db

niwinz 2017-03-02T14:04:14.000629Z

when a password is derived with derive function the salt is publicy appended to the result:

niwinz 2017-03-02T14:04:26.000630Z

bcrypt+sha512$a19816aad5a6dea6c3d927a0fbca8e75$12$c679579c550318d9294c562540526860fc6e8877c7870f85

niwinz 2017-03-02T14:04:42.000631Z

the bold part is the randomly generated salt for that derived password

niwinz 2017-03-02T14:05:16.000632Z

I'm not clearly understand why you need a fixed salt.

dm3 2017-03-02T14:05:37.000633Z

@viebel do you just want to follow the best practice for storing passwords?

Yehonathan Sharvit 2017-03-02T14:05:49.000634Z

@dm3 yes

Yehonathan Sharvit 2017-03-02T14:06:00.000635Z

I’d love to follow the best practice

niwinz 2017-03-02T14:06:05.000636Z

You only need use derive for hash password and later check for verify...

dm3 2017-03-02T14:06:38.000637Z

yep, in this encoding scheme the salt is stored together with the algo, iteration count and the hash

dm3 2017-03-02T14:06:47.000638Z

so check can get everything it needs from the string

dm3 2017-03-02T14:07:54.000639Z

you derive(password) -> hash, store the hash, then on next login check(password, hash)

niwinz 2017-03-02T14:10:35.000640Z

I'm pretty security concerned and buddy-hashers follows the well established best practices for password hashing

dm3 2017-03-02T14:11:14.000641Z

it’s confusing when you don’t know that all the algo parameters are stored in the result of derive

dm3 2017-03-02T14:11:30.000642Z

not sure if documentation mentions that

niwinz 2017-03-02T14:12:29.000643Z

If you find a doc or any other improvement, I'm open to review it 😄

Yehonathan Sharvit 2017-03-02T14:13:49.000644Z

This is exactly what confused me

Yehonathan Sharvit 2017-03-02T14:19:07.000645Z

By the way, why is it better to have a random salt stored in the encrypted password?

dm3 2017-03-02T14:20:26.000646Z

it’s just more convenient, e.g. you only need one column/attribute/property in the database for the whole thing

dm3 2017-03-02T14:21:00.000648Z

or do you mean why salt is needed in general?

Yehonathan Sharvit 2017-03-02T14:21:39.000649Z

I mean: why not using the same salt for all the passwords

Yehonathan Sharvit 2017-03-02T14:21:40.000650Z

?

dm3 2017-03-02T14:22:03.000651Z

you can, but then the attacker only needs to construct a single rainbow table

dm3 2017-03-02T14:23:05.000652Z

to try breaking the (stolen) passwords

dm3 2017-03-02T14:23:14.000653Z

if you have a salt per password, this becomes infeasible

niwinz 2017-03-02T14:26:11.000654Z

basically this avoid detect duplicated passwords

niwinz 2017-03-02T14:26:17.000655Z

in the database

niwinz 2017-03-02T14:27:38.000656Z

because the salt additionally to simple append to the final password string it is also feeded into the hasher

niwinz 2017-03-02T14:28:45.000657Z

the salt should be stored in order to posterior verification, without knowing that salt it will be imposible verify the clear password with "encrypted" one

dm3 2017-03-02T14:29:14.000658Z

hm, duplicate passwords - that’s another interesting reason

dm3 2017-03-02T14:30:14.000659Z

here, a good explanation of my point: http://security.stackexchange.com/questions/16686/recompute-rainbow-table-with-salt

Yehonathan Sharvit 2017-03-02T15:40:31.000661Z

Thanks for your explanations @dm3 and @niwinz

Yehonathan Sharvit 2017-03-02T15:40:51.000662Z

BTW funcool is really really cool 😎

😎 1
niwinz 2017-03-02T15:41:07.000663Z

thanks! \o/