Re: MD5-based passwords - Mailing list pgsql-jdbc

From Barry Lind
Subject Re: MD5-based passwords
Date
Msg-id 3BF01F2F.3040309@xythos.com
Whole thread Raw
In response to MD5-based passwords  (Jeremy Wohl <jeremyw-pgjdbc@igmus.org>)
List pgsql-jdbc
Patch applied.

thanks,
--Barry


Jeremy Wohl wrote:

> On Wed, Nov 07, 2001 at 08:26:49PM -0800, Barry Lind wrote:
>
>>I think I would recommend moving most of this logic into a new class
>>under org.postgresql.util, called MD5.java?? (that is where the
>>UnixCrypt class is located).
>>
>>[...]
>>
>
> OK.  Attached is an abstracted version, with your cast fix.
>
> Appropriate exception handling is still open.  As is indenting.
>
>
>>PS.  When sending diffs please use context diff format (i.e.-c).  It
>>makes it much easier to review.
>>
>
> How about unified? :)
>
> -jeremy
> _____________________________________________________________________
> jeremy wohl ..: http://igmus.org
>
>
> ------------------------------------------------------------------------
>
> --- Connection.java.old    Wed Nov  7 11:19:11 2001
> +++ Connection.java    Thu Nov  8 10:20:13 2001
> @@ -63,6 +63,7 @@
>      private static final int AUTH_REQ_KRB5 = 2;
>      private static final int AUTH_REQ_PASSWORD = 3;
>      private static final int AUTH_REQ_CRYPT = 4;
> +        private static final int AUTH_REQ_MD5 = 5;
>
>      // New for 6.3, salt value for crypt authorisation
>      private String salt;
> @@ -180,22 +181,34 @@
>                      // Get the type of request
>                      areq = pg_stream.ReceiveIntegerR(4);
>
> -                    // Get the password salt if there is one
> +                    // Get the crypt password salt if there is one
>                      if (areq == AUTH_REQ_CRYPT)
>                      {
>                          byte[] rst = new byte[2];
>                          rst[0] = (byte)pg_stream.ReceiveChar();
>                          rst[1] = (byte)pg_stream.ReceiveChar();
>                          salt = new String(rst, 0, 2);
> -                        DriverManager.println("Salt=" + salt);
> +                        DriverManager.println("Crypt salt=" + salt);
> +                    }
> +
> +                    // Or get the md5 password salt if there is one
> +                    if (areq == AUTH_REQ_MD5)
> +                    {
> +                        byte[] rst = new byte[4];
> +                        rst[0] = (byte)pg_stream.ReceiveChar();
> +                        rst[1] = (byte)pg_stream.ReceiveChar();
> +                        rst[2] = (byte)pg_stream.ReceiveChar();
> +                        rst[3] = (byte)pg_stream.ReceiveChar();
> +                        salt = new String(rst, 0, 4);
> +                        DriverManager.println("MD5 salt=" + salt);
>                      }
>
>                      // now send the auth packet
>                      switch (areq)
>                      {
>                      case AUTH_REQ_OK:
> -                        break;
> -
> +                        break;
> +
>                      case AUTH_REQ_KRB4:
>                          DriverManager.println("postgresql: KRB4");
>                          throw new PSQLException("postgresql.con.kerb4");
> @@ -217,6 +230,15 @@
>                          String crypted = UnixCrypt.crypt(salt, PG_PASSWORD);
>                          pg_stream.SendInteger(5 + crypted.length(), 4);
>                          pg_stream.Send(crypted.getBytes());
> +                        pg_stream.SendInteger(0, 1);
> +                        pg_stream.flush();
> +                        break;
> +
> +                    case AUTH_REQ_MD5:
> +                            DriverManager.println("postgresql: MD5");
> +                        byte[] digest = MD5Digest.encode(PG_USER, PG_PASSWORD, salt);
> +                        pg_stream.SendInteger(5 + digest.length, 4);
> +                        pg_stream.Send(digest);
>                          pg_stream.SendInteger(0, 1);
>                          pg_stream.flush();
>                          break;
>
>
> ------------------------------------------------------------------------
>
> package org.postgresql.util;
>
> /**
>  * MD5-based utility function to obfuscate passwords before network transmission
>  *
>  * @author Jeremy Wohl
>  *
>  */
>
> import java.security.*;
>
> public class MD5Digest
> {
>     private MD5Digest() {}
>
>
>     /**
>      * Encodes user/password/salt information in the following way:
>      *   MD5(MD5(password + user) + salt)
>      *
>      * @param user      The connecting user.
>      * @param password  The connecting user's password.
>      * @param salt      A four-character string sent by the server.
>      *
>      * @return  A 35-byte array, comprising the string "md5", followed by an MD5 digest.
>      */
>     public static byte[] encode(String user, String password, String salt)
>     {
>     MessageDigest  md;
>     byte[]         temp_digest, pass_digest;
>     byte[]         hex_digest = new byte[35];
>
>
>     try {
>         md = MessageDigest.getInstance("MD5");
>
>         md.update(password.getBytes());
>         md.update(user.getBytes());
>         temp_digest = md.digest();
>
>         bytesToHex(temp_digest, hex_digest, 0);
>         md.update(hex_digest, 0, 32);
>         md.update(salt.getBytes());
>         pass_digest = md.digest();
>
>         bytesToHex(pass_digest, hex_digest, 3);
>         hex_digest[0] = (byte) 'm'; hex_digest[1] = (byte) 'd'; hex_digest[2] = (byte) '5';
>     } catch (Exception e) {
>         ; // "MessageDigest failure; " + e
>     }
>
>     return hex_digest;
>     }
>
>
>     /**
>      * Turn 16-byte stream into a human-readable 32-byte hex string
>      */
>     private static void bytesToHex(byte[] bytes, byte[] hex, int offset)
>     {
>     final char lookup[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
>                 'a', 'b', 'c', 'd', 'e', 'f' };
>
>     int i, c, j, pos = offset;
>
>     for (i = 0; i < 16; i++) {
>         c = bytes[i] & 0xFF; j = c >> 4;
>         hex[pos++] = (byte) lookup[j];
>         j = (c & 0xF);
>         hex[pos++] = (byte) lookup[j];
>     }
>     }
> }
>
>
> ------------------------------------------------------------------------
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
>



pgsql-jdbc by date:

Previous
From: Barry Lind
Date:
Subject: Re: SQLException: ERROR: oidin: when loading GIF file
Next
From: Barry Lind
Date:
Subject: Re: ResultSet.getDate failure with timestamp column