Re: MD5-based passwords

From: Barry Lind <barry(at)xythos(dot)com>
To: Jeremy Wohl <jeremyw-pgjdbc(at)igmus(dot)org>
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: MD5-based passwords
Date: 2001-11-09 02:15:56
Message-ID: 3BEB3C5C.70004@xythos.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-jdbc

Jeremy,

The revised patch looks fine to me. I will apply it tomorrow (unless
someone comes along objecting to the inclusion of this patch).

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(at)postgresql(dot)org)
>

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2001-11-09 02:17:17 Re: Call for objections: revision of keyword classification
Previous Message Bruce Momjian 2001-11-09 02:05:07 Re: Call for objections: revision of keyword classification

Browse pgsql-jdbc by date

  From Date Subject
Next Message Tom Lane 2001-11-09 02:26:29 Re: MD5-based passwords
Previous Message Bruce Momjian 2001-11-09 02:13:02 Re: MD5-based passwords