Re:Why Canada’s banks have weaker passwords than Twitter or ...
by derefr on Sunday June 08, 2014 @04:22PM
(#7865768)
It seems to me that by taking a good KDF-hash of the user's password, then "compressing" it (either by truncating or re-hashing it to a new output length), you could get it down to a size where the base32 representation of those bytes, would both A. fit into the legacy password field, and B. obey its alphanumeric-only restrictions.
Naively, you'd think the compression would make the password field much more prone to preimage attacks (e.g. JtRing a hacked DB dump), but calculating each attempt would still require a full KDF series, even if large amounts of the KDF's output keyspace are getting conflated at the end. You'd likely have a lot of accidental collisions between passwords that happen to hash to the same value in your restricted keyspace, but they'd be no help in finding a purposeful collision, because the input keyspace would be unlimited.
Of course, if you only have 40 bits of output keyspace available (i.e. a field with a capacity for eight base32 characters), you "only" need to KDF 2^40 passwords to generate a probabilistically-complete rainbow table. So, make sure to salt the compression step with something user-specific, e.g. The UID. One simple method of achieving this would be to have the output look like
This basically means that a successful preimage attack on your compressed KDF be would require a unique collision between the salted and unsalted hash outputs—effectively doubling the output keyspace one would have to search, as well as giving you the regular benefits of per-user salts.
---
...or you could just put the hash of a random opaque token in the password field; stand up a modern, separate server that runs a "password service" (in the SOA architecture sense) to keep a map of full (UID, KDF hash) pairs to the opaque tokens; and then have your web service hit the password service to (potentially) return it a token to use as the password in the conversation with the legacy auth system. You know, either way.
Naively, you'd think the compression would make the password field much more prone to preimage attacks (e.g. JtRing a hacked DB dump), but calculating each attempt would still require a full KDF series, even if large amounts of the KDF's output keyspace are getting conflated at the end. You'd likely have a lot of accidental collisions between passwords that happen to hash to the same value in your restricted keyspace, but they'd be no help in finding a purposeful collision, because the input keyspace would be unlimited.
Of course, if you only have 40 bits of output keyspace available (i.e. a field with a capacity for eight base32 characters), you "only" need to KDF 2^40 passwords to generate a probabilistically-complete rainbow table. So, make sure to salt the compression step with something user-specific, e.g. The UID. One simple method of achieving this would be to have the output look like
This basically means that a successful preimage attack on your compressed KDF be would require a unique collision between the salted and unsalted hash outputs—effectively doubling the output keyspace one would have to search, as well as giving you the regular benefits of per-user salts.---
...or you could just put the hash of a random opaque token in the password field; stand up a modern, separate server that runs a "password service" (in the SOA architecture sense) to keep a map of full (UID, KDF hash) pairs to the opaque tokens; and then have your web service hit the password service to (potentially) return it a token to use as the password in the conversation with the legacy auth system. You know, either way.