Hacker News new | comments | show | ask | jobs | submit login

I think this is catastrophically broken because of a known issue of how SHA-2 breaks its input into blocks: when A is aligned to a block boundary, sha(A || B) = f(sha(A), g(B)).

http://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_con...

In your system, the derived password is a sha digest of a concatentation of other sha digests. It almost has the form sha(sha(SALT) || sha(RESOURCE) || sha(MASTER)), with sha() returning the ascii encoding of the base-16 representation. (The difference is three extra newline characters "\n", which makes things slightly messier). This string representation for sha-512 digests is 128 characters or 1028 bits, and sha-512 uses 1028-bit input chunks, so the final sha() call reads the other three digests aligned on chunk boundaries. (Again, few bits off because of newlines, but this is not fatal).

So DERIVED(RESOURCE) has a form

    DERIVED = sha(sha(SALT) || sha(RESOURCE) || sha(MASTER))
            = f(sha(sha(SALT) || sha(RESOURCE)), g(sha(MASTER)))
where f,g, are known functions. Moreover, f is reversible -- in SHA-512 it is just addition.

So for an attack: given the salt, along with one resource/derived password pair, every other password can be computed. If you know SALT, RESOURCE_1, and DERIVED_1, you know these:

    sha(sha(SALT) || sha(RESOURCE_1))

    DERIVED_1 = f(sha(sha(SALT) || sha(RESOURCE_1)), g(sha(MASTER)))
Because f is reversible, and you know its first argument, you also learn its other argument,

    g(sha(MASTER))
and can calculate any other password, given the resource name. Note you don't learn the master password, nor its sha digest -- you can't reverse the block function g(), not without breaking SHA-2 itself. But that's not necessary.



> I think this is catastrophically broken because of a known issue of how SHA-2 breaks its input into blocks: when A is aligned to a block boundary, sha(A || B) = f(sha(A), g(B)).

If that's the case, wouldn't it suffice to mix A and B, for example with byte-wise XOR?

  password ::= sha(A XOR B)


Though that would be hard to do in a one-line shell script, which was the idea behind the gist.


If this is true for this particular implementation, it may not necessarily doom the concept. You could switch to a standard key generation algorithm such as pbkdf2, which is supported in sjcl and is thus available anywhere that can run javascript.


I have added a link to your comment to the gist in the warning.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: