Closed SoniEx2 closed 10 years ago
You cannot brute-force 504 bits unless you have additional information about them. Even 128 bits far exceeds what all of humanity can currently achieve.
I can bruteforce the 504 bits as 32 bits, actually... (because mt_rand())
This could be bad... https://github.com/sebsauvage/ZeroBin/blob/master/index.php#L288
I don't see how it could be 32 bits. Check this line: https://github.com/sebsauvage/ZeroBin/blob/master/lib/serversalt.php#L7 It's 32 bits * 16 because of the loop.
@Zolmeister
It doesn't matter how many bits you draw from a PRNG, you can't get a higher security level than the seed.
For example when you seed with a 32 bit value, there will only be 4 billion different output sequences, even if those are longer than 32 bits.
I believe mt_rand
uses a 32 bit seed, which is even easier to guess than a random 32 bit value, since it's based on the time. 32 bit values collide pretty often as well, so they're not suitable as salts.
You should use a CRPNG to generate the salt. I know three ways to do that in php:
mcrypt_create_iv(size, MCRYPT_DEV_URANDOM)
(don't use one of the other sources, they're either broken or extremely slow)
despite the name, this works on windowsopenssl_random_pseudo_bytes
is tricky to use since it can return low quality outputs, which you need to check for./dev/urandom
(Linux only)I recommend using mcrypt_create_iv(size, MCRYPT_DEV_URANDOM)
.
@CodesInChaos Thanks, you inspired me to look into PRNG cracking. If you have a minute could you please explain how it would be feasible to attack the server externally to crack the prng? From what I understand, you only need a small sample from the random numbers, but it is only feasible if they are the first random numbers generated with the seed (which in this case I think they are, so it's not a problem). If you don't seed mt_rand(), does it pick a seed at random? (and each time, or just the first time) - if it's each time then running it 16 times would mean cracking 16 separate PRNG seeds right?
Here's what I was thinking (let me know if I've missed something):
Is there a way to work around not having the data_id?
@Zolmeister data_id = paste ID
Soni, you are correct. mt_rand should be replaced as it is not a secure random generator. As you observed you could crack a bigger key using smaller 32bit instances or 64bit instances (depending on 32 or 64 bit php compilation).
Also the generation of the HMAC is ok, I'd probably move SHA1 to be SHA256 but other than that it should be ok. SHA1 has theoretical collisions but the numbers are astronomical making the true use of them very impractical.
@CodesInChaos: Thanks.
mcrypt_create_iv(size, MCRYPT_DEV_URANDOM)
will be added as default, with a fallback to mt_rand()
when not available.
This issue has been fixed in commit https://github.com/sebsauvage/ZeroBin/commit/a24212afda90ca3e4b4ff5ce30d2012709b58a28 Thank you for helping me to improve ZeroBin security.
As the FAQ says, the VizHash salt is server-side... This means all comments use the same salt... Someone could grab their IP + their VizHash and explore/bruteforce 504 bits instead of 536, and then all the IPs can be explored/bruteforced as 32 bits...
(Please note that I don't know how VizHashes really work so sorry if I'm wrong...)