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 here.

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
landing page.
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 man-in-the-middle.

- Marsh

The Cryptography Mailing List
Unsubscribe by sending "unsubscribe cryptography" to majord...@metzdowd.com

Reply via email to