[jcifs] Quick LM Hash question.
Michael B.Allen
mballen at erols.com
Fri Apr 5 19:38:23 EST 2002
On Fri, 5 Apr 2002 00:33:27 -0600
Christopher R.Hertel <crh at ubiqx.mn.org> wrote:
> I am working on figuring out the authentication schemes used by Windows,
> both for my book and for a presentation I'm doing. I've got a quick
> question. My hope is that someone (Mike?) can point me to the specific
> place where this is handled in jCIFS. I've been through the DES and MD4
> code, but that's at a slightly lower level.
>
> Here's the deal. All of the docs I've seen show the LanMan (LM) alorithm
> as:
>
> E(K0K1,D0D1) = E(K0,D0)E(K0,D1)E(K1,D0)E(K1,D1)
>
> This is what Leach wrote, but it doesn't make sense. The result of the
> above is the same as:
>
> E(K0K1,D0D1) = E(K0,D0D1)E(K1,D0D1)
>
> Which just gives two concatonated strings, each the result of encrypting
> the same data with two different keys.
>
> I *think* that what should happen is:
>
> E(K0K1,D0D1) = E(K1, E(K0,D0D1))
>
> So, I'm digging through to find the code that actually does LanMan
> password hashing.
>
> Mike: Where do I look? NegProt?
With what object would you expect to perform encrypted
authentication? It's all right at the top of SmbSession.java:
// KGS!@#$%
static final byte[] S8 = {
(byte)0x4b, (byte)0x47, (byte)0x53, (byte)0x21,
(byte)0x40, (byte)0x23, (byte)0x24, (byte)0x25
};
static void E( byte[] key, byte[] data, byte[] e ) {
byte[] key7 = new byte[7];
byte[] e8 = new byte[8];
for( int i = 0; i < key.length / 7; i++ ) {
System.arraycopy( key, i * 7, key7, 0, 7 );
DES des = new DES( key7 );
des.encrypt( data, e8 );
System.arraycopy( e8, 0, e, i * 8, 8 );
}
}
static byte[] getPreNTLMResponse( String password, byte[] challenge ) {
byte[] p14 = new byte[14];
byte[] p21 = new byte[21];
byte[] p24 = new byte[24];
System.arraycopy( password.toUpperCase().getBytes(), 0, p14, 0, password.length() );
E( p14, S8, p21);
E( p21, challenge, p24);
return p24;
}
static byte[] getNTLMResponse( String password, byte[] challenge ) {
byte[] uni = null;
byte[] p21 = new byte[21];
byte[] p24 = new byte[24];
try {
uni = password.getBytes( "UnicodeLittleUnmarked" );
} catch( UnsupportedEncodingException uee ) {
Log.printStackTrace( "password encryption exception", uee );
}
MD4 md4 = new MD4();
md4.update( uni );
System.arraycopy( md4.digest(), 0, p21, 0, 16 );
E( p21, challenge, p24 );
return p24;
}
This sort of thing is not easy to describe in an e-mail. You just have
to follow through it carefully once and write code as you go along. Of
course you want to run your test example with a challenge and password
copied out of a real SessionSetupAndX call and then compare the
generated hashes.
Mike
--
May The Source be with you.
More information about the jcifs
mailing list