NTLM认证的proxy客户端的Java实现-NTLM_Proxy.java

来源:互联网 发布:区域增长算法代码 编辑:程序博客网 时间:2024/04/29 10:03

程序在Windows和MacOS上编译运行成功。

下面是实现流程的主程序。

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ProxySelector;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.security.Key;
import java.security.MessageDigest;

import javax.crypto.Cipher;

import javax.crypto.spec.SecretKeySpec;

public class NTLM_Proxy {
 
 private static byte[] str2bytes(String str) {
  char[] chars = str.toCharArray();
  byte[] bytes = new byte[chars.length];

  int i;
  for (i = 0; i < chars.length; i++) {
   bytes[i] = (byte) (chars[i] & 0xFF);
  }

  return bytes;
 }

 static void detect_proxy_auth() {
  String auth_method = "<none>";

  try {
   Socket sock = new Socket("192.168.12.240", 8080);
   InputStream sp_in = sock.getInputStream();
   OutputStream sp_out = sock.getOutputStream();
   BufferedReader reader = new BufferedReader(new InputStreamReader(sp_in));
   BufferedOutputStream buff_out = new BufferedOutputStream(sp_out,1460);

   /* authenticate against a proxy host */
   String connect = "CONNECT " + "10.4.59.20" + ":" + 443
     + " HTTP/1.0/r/n/r/n";

   /* send the CONNECT call */
   /* since we use 1-byte chars */
   buff_out.write(str2bytes(connect), 0, connect.length());
   buff_out.flush(); /* no more to write */

   /* read the response */
   String header;
   while ((header = reader.readLine()) != null) {
    if (header.length() == 0) {
     break; /* end of headers */
    }
    header.trim();
    System.out.println("Recv:" + header);
   }

   /* close the connection now since we don't need it */
   sock.close();
   sock = null;

   /* if authentication is required, do it now */

   System.out.println("ntlm");

   NTLM ntlm = new NTLM();
   
   String s = ntlm.getResponseFor("", "user", "passwd", "", "");
   System.out.println("ret:" + s);

   sock = new Socket("192.168.12.240", 8080);
   sp_in = sock.getInputStream();
   sp_out = sock.getOutputStream();
   reader = new BufferedReader(new InputStreamReader(sp_in));
   buff_out = new BufferedOutputStream(sp_out, 1460);

   /* authenticate against a proxy host */
   connect = "CONNECT 10.4.59.20:443 HTTP/1.0/r/nProxy-Authorization: NTLM " + s + "/r/n/r/n";

   /* send the CONNECT call */
   /* since we use 1-byte chars */
   buff_out.write(str2bytes(connect), 0, connect.length());

   buff_out.flush(); /* no more to write */

   /* read the response */
   // String header;
   header = "";
   while ((header = reader.readLine()) != null) {
    if (header.length() == 0) {
     break; /* end of headers */
    }
    header.trim();
    System.out.println("Recv:" + header);

    /* authenticate against a proxy host */
    if (header.toLowerCase().startsWith("proxy-authenticate")) {
     auth_method = header.substring(header.indexOf(":") + 6)
       .trim();
     System.out.println("auth_method: " + auth_method);
    }
   }

   /* close the connection now since we don't need it */
  // sock.close();
  // sock = null;
   String s1 = ntlm.getResponseFor(auth_method, "user", "passwd","", "");
   
   //sock = new Socket("192.168.12.240", 8080);
   sp_in = sock.getInputStream();
   sp_out = sock.getOutputStream();
   reader = new BufferedReader(new InputStreamReader(sp_in));
   buff_out = new BufferedOutputStream(sp_out, 1460);

   /* authenticate against a proxy host */
   connect = "CONNECT 10.4.59.20:443 HTTP/1.0/r/n";
   
   String keepalive = "Proxy-Connection: Keep-Alive/r/n/r/n";
   String AuthorizationStr = "Proxy-Authorization: NTLM " + s1 + "/r/n/r/n";

   /* send the CONNECT call */
   /* since we use 1-byte chars */
   buff_out.write(str2bytes(connect), 0, connect.length());
   buff_out.write(str2bytes(AuthorizationStr), 0, AuthorizationStr.length());
   /* since we use 1-byte chars */
   buff_out.write(str2bytes(keepalive), 0, keepalive.length());
   buff_out.flush(); /* no more to write */

   /* read the response */
   // String header;
   header = "";
   while ((header = reader.readLine()) != null) {
    if (header.length() == 0) {
     break; /* end of headers */
    }
    header.trim();
    System.out.println("OK! Recv:" + header);
   }

   /* close the connection now since we don't need it */
   sock.close();
   sock = null;

   // return;

  } catch (Exception e) {
   /* detect no proxy, continue the next step, don't fail */
  }
 }

 public static void main(String arg[]) {
  detect_proxy_auth();
 }
}