# Encrypt hash using hash of hash?

I wonder what is wrong with this scheme for authentication.

1. Server sends random challenge, C
2. Client returns (C, B(P)) encrypted in H(B(P)) where B(P) is high work factor salted hash of the user passphrase (e.g., bcrypt), and H() is a low work factor hash
3. Server has K = H(B(P)) in database, and can use it to decrypt (C,B(P)) and verify that H(B(P)) = K and that C is equal to the challenge

I wonder is B(P) adequately protected by encryption in key = H(B(P)) when sent over the network? Or, other problems?

EDIT: Let me clarify based on comments. I obscured the main question by splitting the password hash function into 2 stages. I think the answer to my question is the same if there is no B(P) and H() has high work factor. So, client is submitting (C,passphrase) encrypted in H(passphrase). Server knows H(passphrase), as in typical password authentication, so can decrypt. Then can compute H(passphrase) to verify client knows passphrase. It is like classic bcrypt based authentication, but using H(passphrase), rather than SSL, to secure the transport. My concern is how to safely do encryption when the key is derived from the data being encrypted.

The reason for the 2 stage H(B(P)) in my original question is to minimize load on the server, which is the main aim of the protocol, to allow run of the mill hardware to separate wheat from chaff in face of gbps DoS attacks.

EDIT2: Also, I left out how the server proves to the client that it also knows K, which is necessary to prevent active man in the middle. In step 2 the client includes a random session key encrypted in K, which is used to compute a message authentication code on all subsequent messages, including the server return.

• How does the server ever learn K = H(B(P))? Also, what are your goals? What is the standard approach for what you're trying to accomplish, how does it fall short of your security requirements, and how do you believe this scheme improves upon the situation? – Stephen Touset Oct 9 '15 at 22:38
• The server learns K at account creation time, as in other password based authentication. More standard approach would be SRP, which would be fine, if enhanced with bcrypt or similar to guard against database exposure. It falls short because I don't have an implementation, have seen mention of DoS vulnerabilities in one implementation, and also potential patent infringement. I can do the above with standard primitives that I am comfortable working with. – user1055568 Oct 9 '15 at 23:00
• You're encrypting (C, B(P)) with K = H(B(P)), but you never send K to the server. If you send K to the server, an eavesdropper can decrypt (C, B(P)), so there's no point in encrypting it in the first place. Furthermore, combining standard primitives is no less prone to error than inventing your own wholesale. – Stephen Touset Oct 9 '15 at 23:13
• K is the pre-established shared secret. Like simple challenge-response, but knowing K alone is not enough, client must also know H() pre-image B(P). Or, like usual password hash techniques, but using encryption in K to secure the transport, instead of SSL. – user1055568 Oct 9 '15 at 23:16
• It might be helpful if you explained how the client and server pre-establish K. That said, if an attacker knows P, the can trivially calculate K and B(P). If an attacker doesn't know P, what attack does this thwart? – Stephen Touset Oct 9 '15 at 23:23

So your idea is that the client does the work in calculating the slow hash $B(P)$, and proves that to the server by using a hash as an encryption key. It is definitely not a standard way to do things, and has some problems.

In particular, any eavesdropped can trivially launch an offline dictionary attack on the password, so it is like your normal password database was constantly compromised (which should normally lead to "change your password" emails being sent). That means any passwords that are simple enough to be attacked are completely unprotected.

Instead, I would second the suggestion of using TLS. Even if you can come up with a strong password authentication system that works in the clear, you need authenticated encryption to prevent eavesdroppers from reading the authenticated content etc.

If TLS is simply out of the question, you could use SRP. It, too lets you offload all the hard work of using e.g. bcrypt to the client, by using as B(P) as the SRP password: the server only uses the verifier, meaning it does not need to do the calculation. Unlike your protocol, it prevents both passive attacks on the authentication (as well as MITM). However, you should use the agreed key to authenticate and encrypt the rest of the session, or an attacker can just jump in at that point, so complexity is not that much less than TLS.

(You mention patent concerns. IANAL, but Stanford has a royalty free patent grant for implementing RFC 2945, and anyway the patent may already have expired.)

• I was depending on high work factor B(P) to thwart the offline dictionary attack, but I agree that should be last line of defense. I will look again for a good SRP implementation. My problem with TLS is it is vulnerable to SYN flood and other attacks on underlying TCP. This defeats the main aim of authentication for my application, which is to prevent unwanted communications from disrupting use of the system. There are a variety of ad hoc strategies and specialized hardware to mitigate these threats, but I was hoping crypto could help rather an exacerbate. – user1055568 Oct 10 '15 at 14:05
• On complexity, it is the complexity of rejecting authentications that I am concerned about. Accepted authentications presumably generate enough value to carry their weight. After the key exchange I am using AES in EAX mode to protect all subsequent messages. – user1055568 Oct 10 '15 at 14:17
• @user1055568, SRP should not be that much more resource consuming than the protocol you suggested, so I would think that should fit the bill. Hope you can find a good implementation. And yes, using EAX with the agreed key would work for the rest of the session (though GCM is usually more efficient). – otus Oct 10 '15 at 17:20
• Yes, I wanted to use SRP, but was not happy with the implementations I found on first look. I saw that GCM is faster, but fast implementations have large memory footprint (and I would guess slow set-up). The 128-bit EAX implementation I am using has fixed state of around 280 bytes per active key. – user1055568 Oct 10 '15 at 17:32
• @user1055568, yes GCM usually has slower setup. If you care about memory and setup cost more than throughput, then EAX may be the better choice. – otus Oct 10 '15 at 17:43