Java Doc for NTLM.java in  » Web-Crawler » JoBo » com » luigidragone » net » ntlm » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Crawler » JoBo » com.luigidragone.net.ntlm 
Source Cross Reference  Class Diagram Java Document (Java Doc) 


java.lang.Object
   com.luigidragone.net.ntlm.NTLM

NTLM
public class NTLM (Code)

This class implements the Microsoft NTLM authentication protocol.

NTLM is a Microsoft proprietary network authentication protocol used in many situations (e.g. by the Microsoft Proxy Server to authenticate a browser).

It requires a JCE compatible MD4 hash algorithm implementation and a DES with no-padding ECB cipher to compute the requested value.
An open source JCE compatible library is Cryptix JCE and it is available here. We are assuming that the JCE provider is correctly installed and configured. Notice that the Sun JCE implementation proviedes the DES cipher but doesn't provide the MD4 hashing.

To perform an authentication the following information are needed:
  • the host name (with its own domain);
  • the user name (with its own domain);
  • the user password.
Alternatively, the user password can be replaced with its Lan Manager and NT hashed versions. On a Windows system these data can be collected in the registry, otherwise they can be extracted from a SAMBA password file.
Notice that the host and user domain could not be the same.

To start an NTLM authentication procedure (e.g. with a proxy server) build a request message calling NTLM.formatRequest(String,String) formatRequest and send it to the server.
Once the challenge packet has been correctly received extract from it the nonce with NTLM.getNonce(byte[]) getNonce function and use it to compute the reply and build the response message with NTLM.formatResponse(String,String,String,byte[],byte[],byte[]) formatResponse method and send it back to the server.
Repeat the previous steps until the server authenticates the client's identity or a large number of retries has been made. The check of a successful authentication is protocol specific (e.g. code 200 in HTTP), thus it is not performed by this component.

We want to access to the page http://www.server.com/page.html through an NTLM proxy proxy.domain.com that accepts connection on port 80.
We access to proxy from host HOSTDOMAIN\\HOST with the user USERDOMAIN\\user (password "1234567890").
As first step we open a socket connection to proxy server and set up the required object. Notice that we use a keep-alive connection, because NTLM authentication is connection based and the connection must be alive through the whole process.

 Socket s = new Socket("proxy.domain.com", 80);
 s.setKeepAlive(true);
 InputStream is = s.getInputStream();
 OutputStream os = s.getOutputStream();
 BufferedReader r = new BufferedReader(new InputStreamReader(is));
 BufferedWriter w = new BufferedWriter(new OutputStreamWriter(os));
 String host = "HOST";
 String hostDomain = "HOSTDOMAIN";
 String user = "user";
 String userDomain = "USERDOMAIN";
 String password = "1234567890";
 
Then, we format a request message and send it in a HTTP compliant GET message.
 byte[] fstMsg = NTLM.formatRequest(host, hostDomain);
 byte[] fstMsg64 = Codecs.base64Encode(fstMsg);
 System.out.println("NTLM Request Packet: " + new String(fstMsg64));
 w.write("GET http://www.server.com/page.html HTTP/1.0\n");
 w.write("Host: www.server.com\n");
 w.write("Proxy-Connection: Keep-Alive\n");
 w.write("Proxy-Authorization: NTLM " + new String(fstMsg64) + "\n\n");
 w.flush();
 System.out.println("First Message Sent");
 
We wait for the server response and we parse it to extract the nonce.
 String resp = "";
 int contentLength = 0;
 while((line = r.readLine()) != null)
 if(line.length() == 0)
 break;
 if(line.startsWith("Content-Length"))
 contentLength = Integer.parseInt(line.substring(line.indexOf(":") + 1).trim());
 else if(line.startsWith("Proxy-Authenticate"))
 resp = line.substring(line.indexOf(":") + 1).trim();
 r.skip(contentLength);
 System.out.println("Second Message Received");
 System.out.println("Content Length: " + contentLength);
 System.out.println("Proxy-Authenticate: " + resp);
 resp = resp.substring(resp.indexOf(" ")).trim();
 System.out.println("NTLM Chellange Packet: " + resp);
 resp = Codecs.base64Decode(resp);
 byte[] sndMsg = resp.getBytes();
 byte[] nonce = NTLM.getNonce(sndMsg);
 
With the nonce collected in the previous step we create a response message.
 byte[] trdMsg = NTLM.formatResponse(host, user, userDomain,
 NTLM.computeLMPassword(password), NTLM.computeNTPassword(password),
 nonce);
 System.out.println(trdMsg.length);
 byte[] trdMsg64 = Codecs.base64Encode(trdMsg);
 System.out.println("NTLM Response Packet: " + new String(trdMsg64));
 
We sent the message to the server.
 w.write("GET http://www.server.com/page.html HTTP/1.0\n");
 w.write("Proxy-Connection: Keep-Alive\n");
 w.write("Host: www.server.com\n");
 w.write("Proxy-Authorization: NTLM " + new String(trdMsg64) + "\n\n");
 w.flush();
 System.out.println("Third Message Sent");
 
Finally we wait the server reply.
 System.out.println("Server response: " + r.readLine());
 
If the reply is like "HTTP/1.0 200 OK" it has worked fine, else the server response is containing a new nonce.

Notice that despite the computing of hashed passwords and of nonce response is exactly the same of the SMB authentication protocol, the message format is slightly different.
Therefore, the methods NTLM.computeLMPassword(String) computeLMPassword , NTLM.computeNTPassword(String) computeNTPassword and NTLM.computeNTLMResponse(byte[],byte[],byte[],byte[],byte[]) computeNTLMResponse can be used to perform a SMB authentication too.

This implementation is based on:

  • the reverse engineering of the NTLM protocol made by Ronald Tschalär and available here;
  • the documentation about NTLM provided with L0phtCrack 1.5;
  • the "Handbook of Applied Cryptography", freely available here;
  • the C source code of NTLM library in the SAMBA Project.
Nevertheless, because there isn't any official protocol specification publicly available there is any warranty that code works correctly and that it is conforming to Microsoft NTLM protocol.

For implementation reasons only the public members perform argument consistency checks. The public members also catch and hide every exceptions that can be throwed (even though interfaces specify otherwise).


author:
   Luigi Dragone (luigi@luigidragone.com)
version:
   1.0.1
See Also:    NTLM Authentication Scheme for HTTP
See Also:    LanMan and NT Password Encryption in Samba 2.x
See Also:    "Handbook of Applied Cryptography"
See Also:    JCE
See Also:    Cryptix


Field Summary
final protected static  byte[]MAGIC
     The magic number used to compute the Lan Manager hashed password.

Constructor Summary
protected  NTLM()
    

Method Summary
protected static  KeycomputeDESKey(byte[] keyData, int offset)
    

Computes an odd DES key from 56 bits represented as a 7-bytes array.

public static  byte[]computeLMPassword(String password)
     Computes the Lan Manager hashed version of a password.
public static  voidcomputeNTLMResponse(byte[] lmPassword, byte[] ntPassword, byte[] nonce, byte[] lmResponse, byte[] ntResponse)
    

Computes the NTLM response to the nonce based on the supplied hashed passwords.

public static  byte[]computeNTPassword(String password)
     Computes the NT hashed version of a password.
protected static  byte[]encrypt(byte[] keys, byte[] plaintext)
     Encrypts the 8-bytes plain text three times with the 3 56-bits DES keys and puts the result in a 24-bytes array.
public static  byte[]formatRequest(String host, String hostDomain)
    

Builds a request message for the host of the specified domain that can be send to the server to start the NTLM protocol.

The returned message should be encoded according to protocol specific rules (e.g.

public static  byte[]formatResponse(String host, String user, String userDomain, byte[] lmPassword, byte[] ntPassword, byte[] nonce)
    

Builds the nonce response message.

It requires the Lan Manager and NT hashed version of user password, that can be computed from the cleartext version by NTLM.computeNTPassword(String) computeNTPassword and NTLM.computeNTLMResponse(byte[],byte[],byte[],byte[],byte[]) computeNTLMResponse , and the nonce obtained from the server by NTLM.getNonce(byte[]) getNonce .
The returned message should be encoded according to protocol specific rules (e.g.

protected static  bytegetHiByte(char c)
    
protected static  bytegetLoByte(char c)
    
public static  byte[]getNonce(byte[] msg)
    

Extracts from the server challenge response the nonce required to perform the authentication.

The received message should be decoded according to protocol specific rules (e.g.

protected static  shortswapBytes(short s)
    
protected static  intunsignedByteToInt(byte b)
    

Converts an unsigned byte to an unsigned integer.


Field Detail
MAGIC
final protected static byte[] MAGIC(Code)
The magic number used to compute the Lan Manager hashed password.




Constructor Detail
NTLM
protected NTLM()(Code)




Method Detail
computeDESKey
protected static Key computeDESKey(byte[] keyData, int offset) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException(Code)

Computes an odd DES key from 56 bits represented as a 7-bytes array.

Keeps elements from index offset to index offset + 7 of supplied array.


Parameters:
  keyData - a byte array containing the 56 bits used to compute the DES key
Parameters:
  offset - the offset of the first element of the 56-bits key data the odd DES key generated
exception:
  InvalidKeyException -
exception:
  NoSuchAlgorithmException -
exception:
  InvalidKeySpecException -



computeLMPassword
public static byte[] computeLMPassword(String password) throws IllegalArgumentException, NoSuchPaddingException, NoSuchAlgorithmException(Code)
Computes the Lan Manager hashed version of a password.
Parameters:
  password - the user password the Lan Manager hashed version of the password in a 16-bytes array
exception:
  IllegalArgumentException - if the supplied password is null
exception:
  javax.crypto.NoSuchPaddingException - if there isn't any suitable padding method
exception:
  NoSuchAlgorithmException - if there isn't any suitable cipher algorithm



computeNTLMResponse
public static void computeNTLMResponse(byte[] lmPassword, byte[] ntPassword, byte[] nonce, byte[] lmResponse, byte[] ntResponse) throws IllegalArgumentException, NoSuchPaddingException, NoSuchAlgorithmException(Code)

Computes the NTLM response to the nonce based on the supplied hashed passwords.

If the hashed password are not available they can be computed from the cleartext password by the means of NTLM.computeLMPassword(String) computeLMPassword and NTLM.computeNTPassword(String) computeNTPassword methods.


Parameters:
  lmPassword - a 16-bytes array containing the Lan Manager hashed password
Parameters:
  ntPassword - a 16-bytes array containing the Lan Manager hashed password
Parameters:
  nonce - a 8-bytes array representing the server's nonce
Parameters:
  lmResponse - a 24-bytes array that will contain the Lan Manager response after the method invocation
Parameters:
  ntResponse - a 24-bytes array that will contain the NT response after the method invocation
exception:
  IllegalArgumentException - if a parameter has an illegal size
exception:
  javax.crypto.NoSuchPaddingException - if there isn't any suitable padding method
exception:
  NoSuchAlgorithmException - if there isn't any suitable cipher algorithm



computeNTPassword
public static byte[] computeNTPassword(String password) throws IllegalArgumentException, NoSuchAlgorithmException(Code)
Computes the NT hashed version of a password.
Parameters:
  password - the user password the NT hashed version of the password in a 16-bytes array
exception:
  IllegalArgumentException - if the supplied password is null
exception:
  NoSuchAlgorithmException - if there isn't any suitable cipher algorithm



encrypt
protected static byte[] encrypt(byte[] keys, byte[] plaintext) throws InvalidKeyException, NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException, ShortBufferException(Code)
Encrypts the 8-bytes plain text three times with the 3 56-bits DES keys and puts the result in a 24-bytes array.
Parameters:
  keys - a 21-bytes array containing 3 56-bits DES keys
Parameters:
  plaintext - a 8-bytes array to be encrypted a 24-bytes array containing the plaintext DES encrypted with the supplied keys
exception:
  InvalidKeyException -
exception:
  NoSuchAlgorithmException -
exception:
  javax.crypto.NoSuchPaddingException -
exception:
  InvalidKeySpecException -
exception:
  BadPaddingException -
exception:
  IllegalBlockSizeException -
exception:
  ShortBufferException -



formatRequest
public static byte[] formatRequest(String host, String hostDomain) throws IOException(Code)

Builds a request message for the host of the specified domain that can be send to the server to start the NTLM protocol.

The returned message should be encoded according to protocol specific rules (e.g. base 64 encoding).
The message format is discussed here.


Parameters:
  host - the name of the host that is authenticating
Parameters:
  hostDomain - the name of the domain to which the host belongs the request message to send to server to open an authentication procedure
exception:
  IOException - if an error occurs during the message formatting
See Also:    NTLM Authentication Scheme for HTTP



formatResponse
public static byte[] formatResponse(String host, String user, String userDomain, byte[] lmPassword, byte[] ntPassword, byte[] nonce) throws IllegalArgumentException, IOException, NoSuchAlgorithmException, NoSuchPaddingException(Code)

Builds the nonce response message.

It requires the Lan Manager and NT hashed version of user password, that can be computed from the cleartext version by NTLM.computeNTPassword(String) computeNTPassword and NTLM.computeNTLMResponse(byte[],byte[],byte[],byte[],byte[]) computeNTLMResponse , and the nonce obtained from the server by NTLM.getNonce(byte[]) getNonce .
The returned message should be encoded according to protocol specific rules (e.g. base 64 encoding).
The message format is discussed here.


Parameters:
  host - the name of the host that is authenticating
Parameters:
  user - the name of the user
Parameters:
  userDomain - the name of the domain to which the user belongs
Parameters:
  lmPassword - a 16-bytes array containing the Lan Manager hashed password
Parameters:
  ntPassword - a 16-bytes array containing the NT hashed password
Parameters:
  nonce - a 8-byte array containing the nonce sent by server to reply to the request message the challenge response message to send to server to complete the authentication procedure
exception:
  IOException - if an error occurs during the message formatting
exception:
  IllegalArgumentException - if a parameter has an illegal size
exception:
  javax.crypto.NoSuchPaddingException - if there isn't any suitable padding method
exception:
  NoSuchAlgorithmException - if there isn't any suitable cipher algorithm
See Also:    NTLM Authentication Scheme for HTTP



getHiByte
protected static byte getHiByte(char c)(Code)



getLoByte
protected static byte getLoByte(char c)(Code)



getNonce
public static byte[] getNonce(byte[] msg) throws IllegalArgumentException(Code)

Extracts from the server challenge response the nonce required to perform the authentication.

The received message should be decoded according to protocol specific rules (e.g. base 64 encoding).
The message format is discussed here.


Parameters:
  msg - a byte array containing the server challenge message
exception:
  IllegalArgumentException - if a parameter has an illegal size
See Also:    NTLM Authentication Scheme for HTTP



swapBytes
protected static short swapBytes(short s)(Code)



unsignedByteToInt
protected static int unsignedByteToInt(byte b)(Code)

Converts an unsigned byte to an unsigned integer.

Notice that Java bytes are always signed, but the cryptographic algorithms rely on unsigned ones, that can be simulated in this way.
A bit mask is employed to prevent that the signum bit is extended to MSBs.




Methods inherited from java.lang.Object
native protected Object clone() throws CloneNotSupportedException(Code)(Java Doc)
public boolean equals(Object obj)(Code)(Java Doc)
protected void finalize() throws Throwable(Code)(Java Doc)
final native public Class getClass()(Code)(Java Doc)
native public int hashCode()(Code)(Java Doc)
final native public void notify()(Code)(Java Doc)
final native public void notifyAll()(Code)(Java Doc)
public String toString()(Code)(Java Doc)
final native public void wait(long timeout) throws InterruptedException(Code)(Java Doc)
final public void wait(long timeout, int nanos) throws InterruptedException(Code)(Java Doc)
final public void wait() throws InterruptedException(Code)(Java Doc)

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.