Florent Daigniere writes: > On Thu, 2016-12-22 at 11:22 +0100, Arne Babenhauserheide wrote: >> > > Is it somehow possible to decrypt parts of >> > > the store at random in the hope of hitting a random uploaded >> > > private >> > > key >> > > (a variant of the birthday attack against the password which would >> > > avoid >> > > having to query the network for each check)? >> > > >> > >> > Of course it is. Your scheme is completely broken; at the very least >> > the >> > "passphrase" should be salted, hashed and iterated... and yes, that >> > means getting the user to remember the salt too. >> >> The passphrase must be as strong as would be needed for passphrase >> plus salt. >> >> For hashing and iterating: Is that of practical utility when I’m >> sticking the password into a KSK in the end? Isn’t the cost of >> attacking >> the KSK much higher than the cost of hashing and iterating? >> >> (this is my core question here: what’s the cost of attacking a >> randomly generated KSK?) > > The answer is in src/freenet/keys/ClientKSK.java > > It's designed to be fast, not secure... so unless you iterate it, I > think that it is madness.
I think I see how to address that (described in the next paragraph). But for the sake of sharing better practices than what I used, this is what I got wrong: - The decryption keys of WoT IDs have to be considered public knowledge, so anything uploaded to USK@…/ can be attacked offline by trying to decrypt locally stored chunks. - KSK does actually hash and iterate, but it is designed to be fast, therefore the keys must be very long to avoid rainbow-table attacks, and whatever is used in a KSK in large quantities must be iterated to increase the cost of offline attacks on whatever the node has in store. A salt could avoid that. I think the following improved design should address the issues: - The recovery secret will be of the format <creation year>/<part1>/<part2> with part1 having about 45 bits and part2 having about 100 bits of entropy. - Recovery works in four steps: - Retrieve KSK@<prefix><part1>--wotid. This contains <name>@<WoT ID> - Use pbkdf2_sha256 from passlib[1] with <part2> as key and the <WoT ID> as salt to generate a secret with sufficient iterations to make en-masse local storage decryption attacks infeasible. This gives <salted-secret> - Retrieve KSK@<prefix><salted-secret>--insertkey. Use it as <insertkey> - (Re-)create the WoT ID using <name> and <insertkey>. Example recovery secret: 2016/c1n8-83cE/aRUk*DDWL+4Sps_1LgM Do you see remaining problems with the scheme? (the security of the 45bit part1 only need to suffice to make accidental collisions sufficiently unlikely. The WoT ID as salt should be considered public knowledge) Best wishes, Arne [1]: See https://passlib.readthedocs.io/en/stable/ and https://www.public keyberciti.biz/python-tutorials/securely-hash-passwords-in-python/ pbkdf2 is the only algorithm in there which does not require shipping compiled code, therefore I cannot use one of the stronger methods like argon2 or bcrypt. _______________________________________________ Devl mailing list Devl@freenetproject.org https://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl