📄 x6569.htm
字号:
><P
><PRE
CLASS="SCREEN"
>secret1ED34A55</PRE
></P
><P
>which is</P
><P
><PRE
CLASS="SCREEN"
>03ea09f012493415908d63dcb1f6dbdb9bfc09ba</PRE
></P
><P
>The digested password is transmitted to the server inside the
<TT
CLASS="LITERAL"
><digest/></TT
> tag.</P
><P
><TT
CLASS="LITERAL"
>mod_auth_digest</TT
> is unlike the other two modules in
that it doesn't take any responsibility for storing passwords; it leaves
that to mod_auth_plain, as the plaintext password is needed to be re-hashed
with a new random suffix each time.</P
></DD
><DT
>Advantages</DT
><DD
><P
>No plaintext password is transmitted across the wire from client to server,
and only a small amount of computation is required - a single SHA1 hash
process.</P
></DD
><DT
>Disadvantages</DT
><DD
><P
>The password is still stored in plaintext on the server. </P
></DD
></DL
></DIV
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-6-SECT-5.3.1.3"
><I
CLASS="EMPHASIS"
>Zero-Knowledge</I
> Authentication Method</A
></H3
><P
>The zero-knowledge authentication method is so called as the server
requires no knowledge of the password in order to check the credentials.
It makes use of the same hashing algorithm used in the digest authentication
method.</P
><P
></P
><DIV
CLASS="VARIABLELIST"
><DL
><DT
>Method</DT
><DD
><P
>Just as <TT
CLASS="LITERAL"
>mod_auth_plain</TT
> is responsible for storing the
password (in plaintext) when a user is created or when the password is changed,
so <TT
CLASS="LITERAL"
>mod_auth_0k</TT
> is responsible for storing
<I
CLASS="EMPHASIS"
>its version</I
> of the password, or in fact the information
it needs (originally <I
CLASS="EMPHASIS"
>based</I
> on the password) to check
the client's credentials in a zero-knowledge authentication process. </P
><P
>As we know from the user registration and password change processes, any
new password is supplied to the server in plaintext. This is where a
secure (SSL) connection is critical for complete security. While the
<TT
CLASS="LITERAL"
>mod_auth_plain</TT
> module just stores that password as-is,
the <TT
CLASS="LITERAL"
>mod_auth_0k</TT
> module stores a sequenced hash of
the password instead. </P
><P
>What does this mean?</P
><P
>The idea is this: the server stores a value which
is the password hashed with an arbitrary string token multiple (N) times,
recursively. It doesn't store the password itself.
It remembers how many times it has been hashed (N).</P
><P
>Whenever a client
wants to authenticate, the server sends the client the string token,
and the value of N. The client, having obtained the password from the
user, performs the same iterative hashing sequence
that the server performed when it was originally given the password,
but performs the sequence N-1 times. It passes the result of this
sequence to the server, which does one more hash to go from N-1 to N,
and compares what it gets with what it has stored. If they match,
authentication is successful, and the server stores the N-1 hash passed from
the client and decrements N, ready for next time. </P
><P
>The N-1 hash value is passed by the client to the server in the
<TT
CLASS="LITERAL"
><hash/></TT
> tag.</P
><P
>By way of illustration, <A
HREF="x6569.htm#JABTDG-CH-6-FIG-2"
>Figure 6-2</A
> shows a small
Perl script that a
<B
CLASS="COMMAND"
>telnet</B
> user can use to make the necessary
hashing computations when wishing to authenticate with a Jabber
server using the zero-knowledge method.</P
><DIV
CLASS="FIGURE"
><A
NAME="JABTDG-CH-6-FIG-2"
></A
><P
><B
>Figure 6-2. A script implementing the client-side zero-knowledge process</B
></P
><PRE
CLASS="SCREEN"
>#!/usr/bin/perl -w
use strict;
use Digest::SHA1 qw(sha1_hex);
use Getopt::Std;
our($opt_p, $opt_t, $opt_s);
getopt('pts');
unless ($opt_p and $opt_t and $opt_s)
{
print "Usage: $0 -p <password> -t <token> -s <sequence>\n";
exit;
}
# Initial hash of password
my $hash = sha1_hex($opt_p);
# Sequence 0: hash of hashed-password and token
$hash = sha1_hex($hash.$opt_t);
# Repeat N-1 times
$hash = sha1_hex($hash) while $opt_s--;
print "$hash\n";</PRE
></DIV
><P
>Pass the data to the script via the parameters, using the values
obtained from the response to the initial IQ get. Use the value
that the script produces for the value to send in the
<TT
CLASS="LITERAL"
><hash/></TT
> tag.</P
></DD
><DT
>Advantages</DT
><DD
><P
>No password is stored on the server. No (plaintext) password is transmitted
from client to server.</P
></DD
><DT
>Disadvantages</DT
><DD
><P
>This method is slightly more compute-intensive than the other methods.
There is still a security weak spot in the procedure, when the password
is set or re-set (required when the counter N reaches zero), as it must
be passed in plaintext.</P
></DD
></DL
></DIV
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-6-SECT-5.3.2"
>Choosing the Authentication Method</A
></H2
><P
>Now we know a little bit about the authentication methods, let's jump
back to the initial IQ get query in <A
HREF="x6569.htm#JABTDG-CH-6-EX-3"
>Example 6-3</A
>:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get'>
<query xmlns='jabber:iq:auth'>
<username>dj</username>
</query>
</iq>
RECV: <iq type='result'>
<query xmlns='jabber:iq:auth'>
<username>dj</username>
<password/>
<digest/>
<sequence>496</sequence>
<token>3B2DEEC0</token>
<resource/>
</query>
</iq></PRE
></P
><P
>What we're actually seeing here is the result of the authentication
modules announcing their readiness to authenticate the user
<TT
CLASS="LITERAL"
>dj</TT
>. The query is passed to each of the modules.
<TT
CLASS="LITERAL"
>mod_auth_plain</TT
> announces its readiness by inserting
the <TT
CLASS="LITERAL"
><password/></TT
> flag,
<TT
CLASS="LITERAL"
>mod_auth_digest</TT
> with the
<TT
CLASS="LITERAL"
><digest/></TT
> flag, and
<TT
CLASS="LITERAL"
>mod_auth_0k</TT
> inserts the
<TT
CLASS="LITERAL"
><sequence/></TT
> and
<TT
CLASS="LITERAL"
><token/></TT
> tags and values, which is
what the client will need it if wishes to authenticate using the
zero-knowledge method. The <TT
CLASS="LITERAL"
><resource/></TT
>
tag, which is required in any authentication, is finally added before
the result is returned.</P
><P
>This way, the IQ result can convey which authentication methods are
available - if the <TT
CLASS="LITERAL"
>mod_auth_plain</TT
> and
<TT
CLASS="LITERAL"
>mod_auth_digest</TT
> modules were to be commented out in the
module load directive list, as we saw earlier, then the IQ result would
look like this:</P
><P
><PRE
CLASS="SCREEN"
>RECV: <iq type='result'>
<query xmlns='jabber:iq:auth'>
<username>dj</username>
<sequence>496</sequence>
<token>3B2DEEC0</token>
<resource/>
</query>
</iq></PRE
></P
><P
>that is, without the <TT
CLASS="LITERAL"
><password/></TT
> or
<TT
CLASS="LITERAL"
><digest/></TT
> tags.</P
><P
>At the beginning of this section on User Authorization, we noted that
the IQ get in the <TT
CLASS="LITERAL"
>jabber:iq:auth</TT
> namespace was
strongly recommended, before proceeding with the IQ set. This was
primarily to be able to check what authentication methods were supported.
However, as you can see here, it is in fact <I
CLASS="EMPHASIS"
>essential</I
>
in the case of the zero-knowledge authentication method, because without the
<TT
CLASS="LITERAL"
><sequence/></TT
> and
<TT
CLASS="LITERAL"
><token/></TT
> information, we cannot begin
our hashing sequence.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-6-SECT-5.3.3"
>Password Errors and Retries</A
></H2
><P
>If you don't supply all the required parameters, you are notified with
a 406 "Not Acceptable" error:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='set'>
<query xmlns='jabber:iq:auth'>
<username>dj</username>
<digest>03ea09f012493415908d63dcb1f6dbdb9bfc09ba</digest>
</query>
</iq>
RECV: <iq type='result' id='pthsock_client_auth_ID'>
<query xmlns='jabber:iq:auth'>
<username>dj</username>
<digest>03ea09f012493415908d63dcb1f6dbdb9bfc09ba</digest>
</query>
<error code='406'>Not Acceptable</error>
</iq></PRE
></P
><P
>In this case, no <TT
CLASS="LITERAL"
><resource/></TT
>
value was supplied. The <TT
CLASS="LITERAL"
><resource/></TT
>
value is required,
as it is the key part of the JID that is used to distinguish between multiple
connections as the same user on the same Jabber server.</P
><P
>If you get the password wrong, you receive a 401 "Not Authorized" error.
There is currently no limit on the number of times an authorization attempt
can be made, but the <TT
CLASS="LITERAL"
><karma/></TT
> limits for
the <TT
CLASS="LITERAL"
>c2s</TT
> connections (see <A
HREF="c3612.htm"
>Chapter 5</A
>)
may slow the attempts down.</P
></DIV
></DIV
><H3
CLASS="FOOTNOTES"
>Notes</H3
><TABLE
BORDER="0"
CLASS="FOOTNOTES"
WIDTH="100%"
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN6600"
HREF="x6569.htm#AEN6600"
>[1]</A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>The 'pthsock_client_auth_ID' value for the <TT
CLASS="LITERAL"
>id</TT
>
attribute is placed by the JSM as it processes the IQ set request,
in cases where a value has not been specified. </P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN6681"
HREF="x6569.htm#AEN6681"
>[2]</A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>More information on SHA-1 - Secure Hash Algorithm 1, can be obtained at
<A
HREF="http://www.itl.nist.gov/fipspubs/fip180-1.htm"
TARGET="_top"
>http://www.itl.nist.gov/fipspubs/fip180-1.htm</A
>.</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN6684"
HREF="x6569.htm#AEN6684"
>[3]</A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>There are different types of message digest that can be produced with
this algorithm - binary, hexadecimal and base64. The hexadecimal format
is used here and elsewhere in Jabber.</P
></TD
></TR
></TABLE
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x6351.htm"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.htm"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x6787.htm"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>User Registration</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c6313.htm"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>User Registration Script</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -