On Fri, Oct 24, 2008 at 4:50 AM, Asiri Rathnayake <
asiri.rathnayake(a)gmail.com> wrote:
I have hit a wall trying to implement Digest Access
Authentication for the
xwiki-webdav module. I'll try to be clear as much as possible.
*+ INTRO* : Digest Access Authentication is used to avoid the transmission
of clear text passwords over http for authenticating users. Instead of the
clear text password, following hash (RESPONSE) will be transferred to the
server by client,
HA1 = MD5(username,password,realm)
HA2 = MD5(method,digestURI)
RESPONSE = MD5(HA1,nonce,HA2)
Here the 'nonce' is some weird string token generated by the server for
that
particular client for a particular session. So the RESPONSE instead of the
clear text password will be transferred to the server. For more specific
information about Digest Authentication, you may refer [1].
FYI, a nonce isn't that weird (
http://en.wikipedia.org/wiki/Cryptographic_nonce )
Cryptographic nonce: In security
engineering<http://en.wikipedia.org/wiki/Security_engineering>ng>,
a *nonce* stands for *number used
once*[1]<http://en.wikipedia.org/wiki/Cryptographic_nonce#cite_note-0>…
is similar in spirit to a Nonce
word <http://en.wikipedia.org/wiki/Nonce_word>). It is often a
random<http://en.wikipedia.org/wiki/Randomness>or
pseudo-random <http://en.wikipedia.org/wiki/Pseudo-random> number issued in
an authentication
protocol<http://en.wikipedia.org/wiki/Authentication_protocol>to
ensure that old communications cannot be reused in
*replay attacks <http://en.wikipedia.org/wiki/Replay_attack>*. For instance,
nonces are used in HTTP <http://en.wikipedia.org/wiki/HTTP> digest access
authentication <http://en.wikipedia.org/wiki/Digest_access_authentication>to
calculate an
MD5
<http://en.wikipedia.org/wiki/MD5>password<http://en.wikipedia.org/wiki/Password>.
The nonces are different each time that the 401 authentication
challenge response
code <http://en.wikipedia.org/wiki/List_of_HTTP_status_codes> is presented,
and each client request has a unique sequence number, thus making replay
attacks and dictionary
attacks<http://en.wikipedia.org/wiki/Dictionary_attack>virtually
impossible.
*+ PROBLEM* : Simply put, the way xwiki handles authentication requires the
presentation of a clear text password by the client
(which is not available
with Digest Authentication scheme). What we have with xwiki (on the server
side) is a crypted version of the original password.
One possible solution to overcome this limitation is to store the HA1 value
in our databases (is this possible ?). This is one of the limitations of
Digest Authentication scheme as mentioned in [1] :
*"There is an important problem with implementing Digest access
authentication. This is the requirement that either cleartext passwords or
the HA1 hashes must be known in order to perform client response
validation"
It appears that the presented password response is crypted by a one-time-pad
or session-key <http://en.wikipedia.org/wiki/Session_key>. One thought is a
quick hack: Have an external "login" mechanism outside of Xwiki accessible
over HTTPS:// which changes the password expected to be presented on Xwiki's
end to "RESPONSE=MD5(HA1,nonce,HA2)." In other words, each DAV session, you
need to call "davlogin" presenting the new session key. On successful
authentication, "davlogin" sets Xwiki's mysql db password for the given
user
to "RESPONSE=MD5(HA1,nonce,HA2)." Where "nonce" is the current DAV
session
key.
In other words, you sort of reach-around into the db and twiddle the Xwiki
password of the given user, so that you can directly present your
MD5password, transmit it in the clear (it's already encrypted), and
authenticate directly on that MD5password-string matching exactly -- a sort
of "one time password" version of a "one time pad." Xwiki then
authenticates
based on it's understanding of a password (in the clear), when actually the
password is the MD5password setup specifically for that session. (just
disable the "feature" for "Admin" :-) )
I'm sure there's some better way of doing, this...
Also has this situation changed and how does it affect your plans in the
microsoft world:
http://en.wikipedia.org/wiki/Digest_access_authentication#Browser_Implement…::
A 2002 analysis by eWeek Labs concluded that Internet
Explorer<http://en.wikipedia.org/wiki/Internet_Explorer>Version 5.0,
as well as later versions, implements digest authentication in
a way that does not comply with RFC
2617<http://tools.ietf.org/html/rfc2617>17>.
As a result, Internet Explorer cannot be used as a web client for a server
that complies with the digest authentication
standard.[1]<http://en.wikipedia.org/wiki/Digest_access_authentication#c…
Finally, is there any ways to reuse existing work. For example, in Struts
this appears relatively straightforward:
(
http://www.ddj.com/security/184405885?pgno=1 )
Struts distribution includes a comprehensive JSP HTML tag library that
provides support for interacting with input forms. These tags let you define
HTML forms, checkboxes, input text fields, text areas, radio buttons, and
the like. From Listing One <http://www.ddj.com/security/184405885?pgno=1#l1>,
you can see that integration requires two things be done:
- Calling JavaScript library's *fsSignData* function in HTML form's
*onSubmit
*event.
- Defining a hidden variable to receive PKCS#7 digital signature.
HTML TagLib's *form* tag handles the rendering of HTML forms in the Struts
framework. I introduced a new tag called *signform* that extends the
functionality of the form tag to handle the just mentioned changes. For
this, I created a new Java Class called *SignFormTag* in the
org.apache.struts.taglib.html package that extends and overwrites some of
the methods of the class *FormTag*, which is also in the same package.
Methods *renderFormStartElement()* and *renderSignFormScript()* are
overwritten to call the *fsSignData* function on HTML form's
*onsubmit*event handler. Method
*doEndTag()* is overwritten to introduce the hidden variable that receives
the returned digital signature. Figure
3<http://www.ddj.com/showArticle.jhtml?documentID=ddj0411b&pgno=4>…
the UML class diagram.
This tag creates the hidden variable *<formname>_signature* into which the
digital signature is stored. For example, if the form name is *leaveform* as
defined in Listing One <http://www.ddj.com/security/184405885?pgno=1#l1>,
this tag introduces a hidden variable named *leaveform_signature,* which can
be accessed in the server-side script (Controller).
Further, the *SignForm* tag generates a JavaScript function
named*<formname_sign(form, sigHolder)>
*, where *formname* is the name of the form defined as part of the *
<html:signform>* tag. *form* and *sigHolder* are variables representing HTML
*form* and hidden variable to store a digital signature, respectively. It
also creates a suitable form *onsubmit* event handler that calls the *
formname_sign* function when users press the Submit button on *form*. Any *
onSubmit* function that is defined as part of the Struts framework will be
internally called by this new generated function. This is done behind the
scenes and Struts developers are completely oblivious from this. The only
modification that you have to do is to use the *<html:signform>* tag in
place of the *<html:form>* tag to design signed web forms. This greatly
simplifies the development effort required to create secure web form
applications. Listing Two
<http://www.ddj.com/security/184405885?pgno=1#l2>demonstrates the
aforementioned leave example in Listing
One <http://www.ddj.com/security/184405885?pgno=1#l1>, but is now using the
extended Struts framework.
--
Niels
http://nielsmayer.com