Java 通过代理建立套接字连接

Java 通过代理建立套接字连接,java,security,sockets,ssl,proxy,Java,Security,Sockets,Ssl,Proxy,我发现以下有用的程序可以下载证书。但我的问题是,主机(带有证书)只能通过我们公司的代理访问。 我如何教这个程序通过我们的代理连接 /** * Originally posted at: (not available now) * http://blogs.sun.com/andreas/resource/InstallCert.java * Use: * java InstallCert hostname * Example: *% java InstallCert ecc.fedo

我发现以下有用的程序可以下载证书。但我的问题是,主机(带有证书)只能通过我们公司的代理访问。 我如何教这个程序通过我们的代理连接

/**
 * Originally posted at: (not available now)
 * http://blogs.sun.com/andreas/resource/InstallCert.java
 * Use:
 * java InstallCert hostname
 * Example:
 *% java InstallCert ecc.fedora.redhat.com
 */

import javax.net.ssl.*;

import java.io.*;
import java.net.Socket;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Class used to add the server's certificate to the KeyStore with your trusted
 * certificates.
 */
public class InstallCert {

    public static void main(String[] args) throws Exception {
        String host;
        int port;
        char[] passphrase;
        if ((args.length == 1) || (args.length == 2)) {
            String[] c = args[0].split(":");
            host = c[0];
            port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
            String p = (args.length == 1) ? "changeit" : args[1];
            passphrase = p.toCharArray();
        } else {
            System.out.println("Usage: java InstallCert [:port] [passphrase]");
            return;
        }

        File file = new File("jssecacerts");
        if (file.isFile() == false) {
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("java.home") + SEP + "lib"
                    + SEP + "security");
            file = new File(dir, "jssecacerts");
            if (file.isFile() == false) {
                file = new File(dir, "cacerts");
            }
        }
        System.out.println("Loading KeyStore " + file + "...");
        InputStream in = new FileInputStream(file);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();

        SSLContext context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        X509TrustManager defaultTrustManager = (X509TrustManager) tmf
                .getTrustManagers()[0];
        SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
        context.init(null, new TrustManager[] { tm }, null);
        SSLSocketFactory factory = context.getSocketFactory();

        System.out
                .println("Opening connection to " + host + ":" + port + "...");
        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
        socket.setSoTimeout(10000);
        try {
            System.out.println("Starting SSL handshake...");
            socket.startHandshake();
            socket.close();
            System.out.println();
            System.out.println("No errors, certificate is already trusted");
        } catch (SSLException e) {
            System.out.println();
            e.printStackTrace(System.out);
        }

        X509Certificate[] chain = tm.chain;
        if (chain == null) {
            System.out.println("Could not obtain server certificate chain");
            return;
        }

        BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in));

        System.out.println();
        System.out.println("Server sent " + chain.length + " certificate(s):");
        System.out.println();
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = chain[i];
            System.out.println(" " + (i + 1) + " Subject "
                    + cert.getSubjectDN());
            System.out.println("   Issuer  " + cert.getIssuerDN());
            sha1.update(cert.getEncoded());
            System.out.println("   sha1    " + toHexString(sha1.digest()));
            md5.update(cert.getEncoded());
            System.out.println("   md5     " + toHexString(md5.digest()));
            System.out.println();
        }

        System.out
                .println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
        String line = reader.readLine().trim();
        int k;
        try {
            k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
        } catch (NumberFormatException e) {
            System.out.println("KeyStore not changed");
            return;
        }

        X509Certificate cert = chain[k];
        String alias = host + "-" + (k + 1);
        ks.setCertificateEntry(alias, cert);

        OutputStream out = new FileOutputStream("jssecacerts");
        ks.store(out, passphrase);
        out.close();

        System.out.println();
        System.out.println(cert);
        System.out.println();
        System.out
                .println("Added certificate to keystore 'jssecacerts' using alias '"
                        + alias + "'");
    }

    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;

        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        public X509Certificate[] getAcceptedIssuers() {
            throw new UnsupportedOperationException();
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            throw new UnsupportedOperationException();
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }
    }
}
这样的事情也没有任何好处:

Socket proxy = new Socket("proxy.abc.com", 80);
SSLSocket socket =  (SSLSocket) factory.createSocket(proxy, host, port, false);
我总是会遇到以下例外情况:

Exception in thread "main" java.net.ConnectException: Connection timed out: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:550)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:353)
    at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:71)
    at InstallCert.main(InstallCert.java:72)
线程“main”java.net.ConnectException:连接超时:连接 位于java.net.PlainSocketImpl.socketConnect(本机方法) 位于java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) 位于java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) 位于java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) 位于java.net.socksocketimpl.connect(socksocketimpl.java:366) 位于java.net.Socket.connect(Socket.java:529) 位于com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:550) 位于com.sun.net.ssl.internal.ssl.SSLSocketImpl.(SSLSocketImpl.java:353) 位于com.sun.net.ssl.internal.ssl.sslsocketfactorympl.createSocket(sslsocketfactorympl.java:71) 位于InstallCert.main(InstallCert.java:72)
通过浏览器访问远程主机也仅适用于活动代理。这就是为什么我认为我还需要InstallCert程序的代理。

我在internetz上得到了它,但我对代码进行了一些修改/黑客攻击

当我尝试使用HTTP(S)类型的代理时,我遇到了相同的错误“连接超时:连接”。当我使用SOCKS类型的代理时,这个错误就消失了。但是,当我使用代理176.9.240.109:1080时,出现了错误“连接重置”(我从显示的列表中选择了此代理)。当您不发送类似浏览器的用户代理时,可能会发生这种情况,因此我也对其进行了更新

您提到的系统属性以“http.”或“https.”开头,这意味着它们仅适用于http(S)连接,而不适用于普通套接字连接

在下面修改/破解的代码中,我使用了
HttpsURLConnection
,因此系统属性也可以工作

public class InstallCert {

public static void main(String[] args) throws Exception {

    String httpsUrl = null;
    String host;
    int port;
    char[] passphrase;
    if (args.length == 0) {
        httpsUrl = "https://www.google.com/";
        port = 443;
        host = "www.google.com";
        passphrase = "changeit".toCharArray();
    } else if ((args.length == 1) || (args.length == 2)) {
        String[] c = args[0].split(":");
        host = c[0];
        port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
        String p = (args.length == 1) ? "changeit" : args[1];
        passphrase = p.toCharArray();
    } else {
        System.out.println("Usage: java InstallCert [:port] [passphrase]");
        return;
    }

    File file = new File("jssecacerts");
    if (file.isFile() == false) {
        char SEP = File.separatorChar;
        File dir = new File(System.getProperty("java.home") + SEP + "lib"
                + SEP + "security");
        file = new File(dir, "jssecacerts");
        if (file.isFile() == false) {
            file = new File(dir, "cacerts");
        }
    }
    System.out.println("Loading KeyStore " + file + "...");
    InputStream in = new FileInputStream(file);
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(in, passphrase);
    in.close();

    SSLContext context = SSLContext.getInstance("TLS");
    TrustManagerFactory tmf = TrustManagerFactory
            .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);
    X509TrustManager defaultTrustManager = (X509TrustManager) tmf
            .getTrustManagers()[0];
    SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
    context.init(null, new TrustManager[] { tm }, null);
    SSLSocketFactory factory = context.getSocketFactory();

    System.out.println("Opening connection to " + host + ":" + port + "...");

    URL url = new URL(httpsUrl);
    Proxy p = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("176.9.240.109", 1080));
    HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(p);
    conn.setSSLSocketFactory(factory);
    conn.setConnectTimeout(3000); // 3 seconds.
    conn.setReadTimeout(3000); // 3 seconds
    conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
    try {
        System.out.println("Starting SSL handshake...");
        conn.connect();
        System.out.println();
        System.out.println("No errors, certificate is already trusted");
    } catch (SSLException e) {
        System.out.println();
        e.printStackTrace(System.out);
    } finally {
        conn.disconnect();
    }

    X509Certificate[] chain = tm.chain;
    if (chain == null) {
        System.out.println("Could not obtain server certificate chain");
        return;
    }

    BufferedReader reader = new BufferedReader(new InputStreamReader(
            System.in));

    System.out.println();
    System.out.println("Server sent " + chain.length + " certificate(s):");
    System.out.println();
    MessageDigest sha1 = MessageDigest.getInstance("SHA1");
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    for (int i = 0; i < chain.length; i++) {
        X509Certificate cert = chain[i];
        System.out.println(" " + (i + 1) + " Subject "
                + cert.getSubjectDN());
        System.out.println("   Issuer  " + cert.getIssuerDN());
        sha1.update(cert.getEncoded());
        System.out.println("   sha1    " + toHexString(sha1.digest()));
        md5.update(cert.getEncoded());
        System.out.println("   md5     " + toHexString(md5.digest()));
        System.out.println();
    }

    System.out
    .println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
    String line = reader.readLine().trim();
    int k;
    try {
        k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
    } catch (NumberFormatException e) {
        System.out.println("KeyStore not changed");
        return;
    }

    X509Certificate cert = chain[k];
    String alias = host + "-" + (k + 1);
    ks.setCertificateEntry(alias, cert);

    /*
    OutputStream out = new FileOutputStream("jssecacerts");
    ks.store(out, passphrase);
    out.close();
     */
    System.out.println();
    System.out.println(cert);
    System.out.println();
    System.out
    .println("Added certificate to keystore 'jssecacerts' using alias '"
            + alias + "'");
}

private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

private static String toHexString(byte[] bytes) {
    StringBuilder sb = new StringBuilder(bytes.length * 3);
    for (int b : bytes) {
        b &= 0xff;
        sb.append(HEXDIGITS[b >> 4]);
        sb.append(HEXDIGITS[b & 15]);
        sb.append(' ');
    }
    return sb.toString();
}

private static class SavingTrustManager implements X509TrustManager {

    private final X509TrustManager tm;
    private X509Certificate[] chain;

    SavingTrustManager(X509TrustManager tm) {
        this.tm = tm;
    }

    public X509Certificate[] getAcceptedIssuers() {
        throw new UnsupportedOperationException();
    }

    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        throw new UnsupportedOperationException();
    }

    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        this.chain = chain;
        tm.checkServerTrusted(chain, authType);
    }
}
}
公共类安装证书{
公共静态void main(字符串[]args)引发异常{
字符串httpsUrl=null;
字符串主机;
国际港口;
char[]密码短语;
如果(args.length==0){
httpsUrl=”https://www.google.com/";
端口=443;
host=“www.google.com”;
passphrase=“changeit”。toCharArray();
}else如果((args.length==1)| |(args.length==2)){
字符串[]c=args[0]。拆分(“:”;
主机=c[0];
port=(c.length==1)?443:Integer.parseInt(c[1]);
字符串p=(args.length==1)?“changeit”:args[1];
密码短语=p.toCharArray();
}否则{
println(“用法:javainstallcert[:port][passphrase]”;
返回;
}
File File=新文件(“jssecacerts”);
if(file.isFile()==false){
char SEP=File.separatorChar;
File dir=新文件(System.getProperty(“java.home”)+SEP+“lib”
+SEP+“担保”);
文件=新文件(dir,“jssecacerts”);
if(file.isFile()==false){
文件=新文件(目录,“cacerts”);
}
}
System.out.println(“加载密钥库”+文件+”);
InputStream in=新文件InputStream(文件);
KeyStore ks=KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(in,密码短语);
in.close();
SSLContext context=SSLContext.getInstance(“TLS”);
TrustManagerFactory tmf=TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager默认TrustManager=(X509TrustManager)tmf
.getTrustManager()[0];
SavingTrustManager tm=新的SavingTrustManager(defaultTrustManager);
init(null,new TrustManager[]{tm},null);
SSLSocketFactory=context.getSocketFactory();
System.out.println(“打开到“+主机+”:“+端口+”);
URL=新URL(httpsUrl);
Proxy p=新代理(Proxy.Type.SOCKS,新的InetSocketAddress(“176.9.240.109”,1080));
HttpsURLConnection conn=(HttpsURLConnection)url.openConnection(p);
连接装置插座工厂(工厂);
conn.setConnectTimeout(3000);//3秒。
conn.setReadTimeout(3000);//3秒
conn.setRequestProperty(“用户代理”、“Mozilla/5.0(Windows NT 6.0;WOW64;rv:19.0)Gecko/20100101 Firefox/19.0”);
试一试{
System.out.println(“启动SSL握手…”);
连接();
System.out.println();
System.out.println(“无错误,证书已受信任”);
}捕获(SSE){
System.out.println();
e、 printStackTrace(系统输出);
}最后{
连接断开();
}
X509Certificate[]chain=tm.chain;
如果(链==null){
System.out.println(“无法获取服务器证书链”);
返回;
}
BufferedReader reader=新的BufferedReader(新的InputStreamReader(
系统(in),;
System.out.println();
System.out.println(“服务器发送”+chain.length+“证书:”);
System.out.println();
MessageDigest sha1=MessageDigest.getInstance(“sha1”);
MessageDigest md5=MessageDigest.getInstance(“md5”);
对于(int i=0;ipublic class InstallCert {

public static void main(String[] args) throws Exception {

    String httpsUrl = null;
    String host;
    int port;
    char[] passphrase;
    if (args.length == 0) {
        httpsUrl = "https://www.google.com/";
        port = 443;
        host = "www.google.com";
        passphrase = "changeit".toCharArray();
    } else if ((args.length == 1) || (args.length == 2)) {
        String[] c = args[0].split(":");
        host = c[0];
        port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
        String p = (args.length == 1) ? "changeit" : args[1];
        passphrase = p.toCharArray();
    } else {
        System.out.println("Usage: java InstallCert [:port] [passphrase]");
        return;
    }

    File file = new File("jssecacerts");
    if (file.isFile() == false) {
        char SEP = File.separatorChar;
        File dir = new File(System.getProperty("java.home") + SEP + "lib"
                + SEP + "security");
        file = new File(dir, "jssecacerts");
        if (file.isFile() == false) {
            file = new File(dir, "cacerts");
        }
    }
    System.out.println("Loading KeyStore " + file + "...");
    InputStream in = new FileInputStream(file);
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(in, passphrase);
    in.close();

    SSLContext context = SSLContext.getInstance("TLS");
    TrustManagerFactory tmf = TrustManagerFactory
            .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);
    X509TrustManager defaultTrustManager = (X509TrustManager) tmf
            .getTrustManagers()[0];
    SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
    context.init(null, new TrustManager[] { tm }, null);
    SSLSocketFactory factory = context.getSocketFactory();

    System.out.println("Opening connection to " + host + ":" + port + "...");

    URL url = new URL(httpsUrl);
    Proxy p = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("176.9.240.109", 1080));
    HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(p);
    conn.setSSLSocketFactory(factory);
    conn.setConnectTimeout(3000); // 3 seconds.
    conn.setReadTimeout(3000); // 3 seconds
    conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
    try {
        System.out.println("Starting SSL handshake...");
        conn.connect();
        System.out.println();
        System.out.println("No errors, certificate is already trusted");
    } catch (SSLException e) {
        System.out.println();
        e.printStackTrace(System.out);
    } finally {
        conn.disconnect();
    }

    X509Certificate[] chain = tm.chain;
    if (chain == null) {
        System.out.println("Could not obtain server certificate chain");
        return;
    }

    BufferedReader reader = new BufferedReader(new InputStreamReader(
            System.in));

    System.out.println();
    System.out.println("Server sent " + chain.length + " certificate(s):");
    System.out.println();
    MessageDigest sha1 = MessageDigest.getInstance("SHA1");
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    for (int i = 0; i < chain.length; i++) {
        X509Certificate cert = chain[i];
        System.out.println(" " + (i + 1) + " Subject "
                + cert.getSubjectDN());
        System.out.println("   Issuer  " + cert.getIssuerDN());
        sha1.update(cert.getEncoded());
        System.out.println("   sha1    " + toHexString(sha1.digest()));
        md5.update(cert.getEncoded());
        System.out.println("   md5     " + toHexString(md5.digest()));
        System.out.println();
    }

    System.out
    .println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
    String line = reader.readLine().trim();
    int k;
    try {
        k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
    } catch (NumberFormatException e) {
        System.out.println("KeyStore not changed");
        return;
    }

    X509Certificate cert = chain[k];
    String alias = host + "-" + (k + 1);
    ks.setCertificateEntry(alias, cert);

    /*
    OutputStream out = new FileOutputStream("jssecacerts");
    ks.store(out, passphrase);
    out.close();
     */
    System.out.println();
    System.out.println(cert);
    System.out.println();
    System.out
    .println("Added certificate to keystore 'jssecacerts' using alias '"
            + alias + "'");
}

private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

private static String toHexString(byte[] bytes) {
    StringBuilder sb = new StringBuilder(bytes.length * 3);
    for (int b : bytes) {
        b &= 0xff;
        sb.append(HEXDIGITS[b >> 4]);
        sb.append(HEXDIGITS[b & 15]);
        sb.append(' ');
    }
    return sb.toString();
}

private static class SavingTrustManager implements X509TrustManager {

    private final X509TrustManager tm;
    private X509Certificate[] chain;

    SavingTrustManager(X509TrustManager tm) {
        this.tm = tm;
    }

    public X509Certificate[] getAcceptedIssuers() {
        throw new UnsupportedOperationException();
    }

    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        throw new UnsupportedOperationException();
    }

    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        this.chain = chain;
        tm.checkServerTrusted(chain, authType);
    }
}
}