Are unix/linux sha256/sha512 passwords in /etc/shadow key-strengthened?
Yes. They use a crypt procedure that does a default of 5000 rounds of hashing. The sha256-crypt/sha512-crypt procedure is described here
and in java
Can I change the number of rounds?
Yes. Simply edit /etc/pam.d/passwd
or /etc/pam.d/common-password
(or solaris equivalent) and add 'rounds=73500` at the end of the line that looks similar to:
password [success=2 default=ignore] pam_unix.so obscure sha512 rounds=73500
and then change your password using passwd. Why 73500? Well, timing crypt with rounds=5000, I was getting about 3.4 ms per password. (5000*50/3.4 ~ 73500). You can check if a password in your /etc/shadow files was done an abnormal number of rounds if it looks starts with yourusername:$6$rounds=73500$RFzXZTGB$
where $6$
indicates the crypt procedure used (sha256-crypt is $5$, sha512-crypt $6$) followed by number of rounds and then the salt.
But I want bcrypt; Can I switch to that:
Check /etc/pam.d/ and (1) change all references of pam_unix.so
to pam_unix2.so
(check that the file is there) and (2) then change sha512
to blowfish
in /etc/pam.d/common-password
https://serverfault.com/questions/10585/enable-blowfish-based-hash-support-for-crypt/11685#11685
One noticeable difference between bcrypt vs sha512-crypt; is that bcrypt work-factor scales exponentially; e.g., a work-factor of 12, should take double as long as a work-factor of 11, while sha512-crypt rounds scale linearly (e.g., rounds=10000
should take twice as long as rounds=5000
). This is simply because bcrypt says do 2work-factor rounds. As a quick benchmark on my machine, one bcrypt round is more expensive than a sha512-crypt round; with a rough equivalence of ~4 ms with rounds=5000
or work-factor=6
(26=64 bcrypt-rounds). But as both can be scaled up this should not be an issue until the number of rounds overflow the unsigned 32-bit/64-bit int
(when rounds = 4 billion or 1019 respectively).
Python timing Stuff With sha512-crypt
You can check crypt via python (in linux this performs just as fast as the C version as it just is a thin wrapper for the crypt library written in C)
>>> import crypt
>>> crypt.crypt('testtest', '$6$6LzxTFam$')
In python on my machine with the crypt module it takes about 3.4 ms per sha512-crypt password at 5000 rounds and ~50 ms with 73500 rounds.
>>> import timeit
>>> timer = timeit.Timer("crypt.crypt('testtest', '$6$6LzxTFam$')", setup="import crypt")
>>> timer.timeit(1000)
3.4215329647064209
# with 73500 rounds:
>>> timeit.Timer("crypt.crypt('testtest', '$6$rounds=73500$RFzXTGB$')", 'import crypt').timeit(1000)
50.738550186157227