SRP is for situations where you already have a shared secret between client and server, e.g. as part of a "pairing" procedure which would occur naturally in your context (for instance, SRP has been proposed for Bluetooth peripherals: one device has a screen and displays a code, the other device has a keypad on which the code is entered). For a "fully online" situation where there never is any occasion to obtain such a shared secret, SRP has little advantage. Security has to start somewhere.
In SRP, what the server stores is indeed a sort-of hash of the password -- only "sort-of" because the stored value must also fulfil some mathematical structure so that it can be used in the protocol. That value cannot be immediately used to authenticate as a client, but, like any hashed password, it is indeed susceptible to brute force. The magic of SRP is that observing data packets on the wire is not sufficient to apply a dictionary attack on the password; however, what the server stores allows such an attack (and, in a very general way, this is unavoidable).
In TLS/SRP as currently specified, the value stored on the server is computed as:
x = SHA1(s | SHA1(I | ":" | P))
v = g^x % N
where s
is the salt, I
the user name, P
the password, and v
is that which is stored (x
is not stored). g
and N
are SRP parameters (public). If the attacker can obtain the value v
, then he can "try passwords" by doing the computation above.
This is a salted hash (that's good), but it is also a quite fast hash (that's bad). SRP could be coupled with a good password hashing function (e.g. bcrypt), with the following caveats:
- There is no specified or de facto standard for that. But both client and server must agree on the particular.
- If slow hashing is used, then, when a connection is performed, it must occur on the client, not on the server. So this will run at the speed of the client.