On 09/13/2010 07:24 PM, Ian G wrote:
On 11/09/10 6:45 PM, f...@mail.dnttm.ro wrote:
Essentially, the highest risk we have to tackle is the database.
Somebody having access to the database, and by this to the
authentication hashes against which login requests are verified,
should not be able to authenticate as another user. Which means, I
need an algorithm which should allow the generation of different
hashes for which it can be verified that they stem from the same login
info, without being able to infer this login info from a hash. This
algorithm is the problem I haven't solved yet. Other than that, I see
no way of protecting against a dictionary attack from somebody having
direct access to the database.
flj, I appreciate your systematic and conscientious engineering
approach. But I haven't heard anything in your requirements that make it
sound like a journey outside of well established protocols is justified
There are a few experienced people around here who could probably design
come up with a new custom scheme and get it right the first time. But
the history of most (even professionally-designed) new security
protocols usually includes the later discovery of serious weaknesses.
I don't recall the full discussion, but what you described is generally
handled by public key cryptography, and it is built into HTTPS.
Here's my suggestion:
I have a similar setup going in a reasonably big production environment
and it's working great.
1. In your initial account creation / login, trigger a creation of a
client certificate in the browser.
There may be a way to get a browser to generate a cert or CSR, but I
don't know it. But you can simply generate it at the server side.
1.b. record the client cert as the authenticator in the database.
2. when someone connects, the application examines the cert used, and
confirms the account indicated.
Note that you can get the full client cert presented by the web server
and compare it (or a sufficiently long :-) hash of it) directly with
what you have in the database. There may be no need to check signatures
and so on if your server-side is centralized.
If an unknown cert, transfer to a
2.b note that there is no login per se, each request can as easily check
the client cert listed by Apache.
Most apps will want to ask the human to authenticate explicitly from
time to time for one reason or another.
3. you just need some way to roll-over keys from time to time. Left for
Make sure you have at least some way of revoking and renewing a client
certs, even if it's a code update. Just on the outside chance that, say,
the keys got generated by Debian Etch's RNG or something.
3.b There are some other bugs, but if the approximate scheme works...
Three more recommendations:
Don't put anything sensitive in the X509 cert. Just a minimal userid or
even random junk. You're just looking it up in a database.
Disable TLS renegotiation unless you control both the clients and the
servers and can ensure they're all patched for CVE 2009-3555. Don't
expect to be able to use renegotiation to "hide" the contents public
cert, that never worked against an active attacker anyway.
Use a separate dns name for the https site that accepts client certs
from the one that does not. The reason is that the client cert will have
to be requested on the initial handshake. Requesting a client cert will
cause many browsers to pop-up a dialog. Not something you want on your
secure home page.
Again this is a good scheme, it's the way SSL/TLS has been intended to
be used for authenticated clients since SSLv3. It even offers additional
protections from the server's perspective, too: the server is no longer
forced to transitively trust the union of all trusted root CA certs of
all allowed clients in order to prove the non-existence of a
The Cryptography Mailing List
Unsubscribe by sending "unsubscribe cryptography" to majord...@metzdowd.com