程序在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();
}
}