Question

Ok after experimenting a little bit I found out that resin was calling my AbstractAuthenticator implementation "authenticate" method that takes an HttpDigestCredentials object instead of DigestCredentials (still don't know when is called each one of them) the problem is that HttpDigestCredentials doesn't have a getDigest() method, instead it has a getResponse() method which doesn't return a hash or at least not a comparable one.

After creating my own hash of [[user:realmassword] [nonce] [method:uri]] the hash is very different, in fact I think getResponse() does not return the digest but maybe the server response to the browser?.

Any way this is my debugging log :

USER:user:PASSWORD:password:REALM:resin:METHOD:GET:URI/appe/appe.html:NONCE:HsJzN+j+GQD:CNONCE:b1ad4fa1ba857cac88c202e64528bc0c:CLIENTDIGEST:[B@5dcd8bf7:SERVERDIGEST:I4DkRCh21YG2Mk14iTe+hg==

as you can see both the supposed client nonce is very very different from the server generated nonce, in fact the client nonce doesn't look like a MD5 hash at all.

Please has someone does this before? is there something missing in the HttpDigestCredentials? I know digest is barely used.

Please, I know about SSL but I can't have an SSL certificate just yet so don't tell me "Why don't you use SSL". ;)

Update:

Not sure if was the right thing to do but, as I read before Resin uses base64 format for hashes so I used apache commons-codec-1.6 to use encodeBase64String() method and now the hashes look alike but they are no the same.

I tried both passwordDigest.getPasswordDigest(a1+':'+nonce+':'+a2); passwordDigest.getPasswordDigest(a1+':'+nonce+':'+ncount+':'+cnonce+':'+qop+':'+a2);

and none of them gives the same hash as the one from HttpDigestCredentials.

Was it helpful?

Solution

Ok I finally made it . Weird subject Huh, only two views?

First, digest authentication makes use of user, password, realm, nonce, client_nonce, nonce_count, method, qop, and uri. Basically it uses the full digest spec. So in order to calculate the hash one must calculate it with all the whistles. Is just a matter of calling the get method for each one of the variables from HttpDigestCredentials except for user and password. The user will come in the form of a Principal and the password you must look for it yourself in your DB (in my case a DB4O database).

Then you must create a PasswordDigest object, that will take care of generate a hash with the getPasswordDigest() method, but first one must set the format to hex with passwordDigestObject.setFormat("hex").

There is one for the HA1 getPasswordDigest(user,password,realm) and there is another getPasswordDigest() method that takes just one string and one can use it to generate the rest of the hashes, both HA2 and with the previous hashed HA1 the final hash, of course with the nonce nonce_count client_nonce and qop, of course each one separated by a semicolon.

Then it comes the tricky part, although resin works with base64 encoding for digest when you call the getResponse() method from HttpDigestCredentials it returns a byte array (which is weird) so in order to compare it with your hash what I did was use the Hex.encodeHexString() method from org.apache.commons.codec.binary.Hex and pass the HttpCredentialsDigest getResponse() return value, and that will give a nice hex String to compare.

I was doing it the other way around, I was using the Base64 hash from PasswordDigest and converting the HttpDigestCredentials hash to Base64 and the resulting string were never the same.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top