├── README.md ├── Nodejs ├── axios.js └── superagent.js ├── Java ├── README.md ├── JsoupDemo.java ├── HttpUrlConnectionDemo.java ├── JavaHttpClientDemo.java └── InstallCert.java ├── PHP ├── PHPStreamDemo.php └── PHPCurlDemo.php ├── Python ├── PythonRequestsDemo.py ├── PythonUrllib2Demo.py └── PythonAioHttpDemo.py ├── Go └── GoDemo.go └── Scrapy └── middlewares.py /README.md: -------------------------------------------------------------------------------- 1 | 多贝云HTTP代理使用示例代码 2 | 3 | 注意: 4 | 5 | 1.访问https网站时不要手动设置Proxy-Authorization请求头,详情请参考示例代码. 6 | 7 | 2.关闭keepalive,否则会出现IP不能更换的情况. 8 | 9 | -------------------------------------------------------------------------------- /Nodejs/axios.js: -------------------------------------------------------------------------------- 1 | // 安装执行: npm install axios-https-proxy-fix 2 | // 引入 axios-https-proxy-fix 3 | let axios = require('axios-https-proxy-fix') 4 | 5 | let targetUrl = '目标网站' 6 | let proxy = { 7 | host: '代理服务器域名', 8 | port: '代理服务器端口', 9 | auth: { 10 | username: '代理账号', 11 | password: '代理密码' 12 | } 13 | } 14 | axios.get(targetUrl, {proxy: proxy}) 15 | .then((res) => { 16 | console.log(res.data) 17 | }).catch((err) => { 18 | console.log(err.message) 19 | }) 20 | -------------------------------------------------------------------------------- /Java/README.md: -------------------------------------------------------------------------------- 1 | 注意: 2 | 3 | 对于某些特殊的https网站,需要安装该网站的根证书,不然会提示“Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target” 4 | 5 | 如果遇到这种情况,需要预先安装目标网站的根证书: 6 | 7 | 用InstallCert.java这个脚本进行安装,编译 javac InstallCert.java 运行 java InstallCert(该类为包含main方法的入口类,直接运行即可) 8 | 9 | 在出现提示后,输入1后回车完成(如果你要放弃并退出输入q即可)。 10 | 11 | 执行完毕后,在执行该类的当然目录中找到生成的 jssecacerts 文件,然后拷贝该文件到JDK中,如我的是放到:……\jdk1.8.0_60\jre\lib\security 中。 12 | 13 | 最后再使用之前的Java代码请求HTTPS接口,就不会出现错误了 14 | -------------------------------------------------------------------------------- /PHP/PHPStreamDemo.php: -------------------------------------------------------------------------------- 1 | array( 9 | 'proxy' => 'tcp://域名:端口',//这里设置你要使用的代理服务器域名及端口号 10 | 'request_fulluri' => true, 11 | 'header' => "Proxy-Authorization: Basic $auth", 12 | ), 13 | ); 14 | $cxContext = stream_context_create($aContext); 15 | $sFile = file_get_contents('https://pv.sohu.com/cityjson?ie=utf-8', False, $cxContext); 16 | 17 | echo "headers:".$auth."\n"; 18 | 19 | echo $sFile; 20 | 21 | 22 | 23 | 24 | 25 | ?> 26 | -------------------------------------------------------------------------------- /Python/PythonRequestsDemo.py: -------------------------------------------------------------------------------- 1 | #! -*- encoding:utf-8 -*- 2 | 3 | import requests 4 | 5 | #目标网址 6 | targetUrl = "https://pv.sohu.com/cityjson?ie=utf-8" 7 | 8 | #http代理接入服务器地址端口 9 | proxyHost = "域名" 10 | proxyPort = "端口" 11 | 12 | #账号密码 13 | proxyUser = "账号" 14 | proxyPass = "密码" 15 | 16 | proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % { 17 | "host" : proxyHost, 18 | "port" : proxyPort, 19 | "user" : proxyUser, 20 | "pass" : proxyPass, 21 | } 22 | 23 | proxies = { 24 | "http" : proxyMeta, 25 | "https" : proxyMeta, 26 | } 27 | 28 | result = requests.get(targetUrl, proxies=proxies) 29 | 30 | print result.status_code 31 | print result.text 32 | -------------------------------------------------------------------------------- /Python/PythonUrllib2Demo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #coding:utf-8 3 | 4 | 5 | import urllib2 6 | 7 | 8 | # 要访问的页面 9 | Url = "https://pv.sohu.com/cityjson?ie=utf-8" 10 | 11 | # 接入服务器地址信息 12 | proxyServer = "域名" 13 | proxyPort = "端口" 14 | 15 | # 代理账号密码信息 16 | proxyUser = "账号" 17 | proxyPass = "密码" 18 | 19 | proxyInfo = "http://%(account)s:%(password)s@%(host)s:%(port)s" % { 20 | "host" : proxyServer, 21 | "port" : proxyPort, 22 | "account" : proxyUser, 23 | "password" : proxyPass, 24 | } 25 | 26 | proxy_handler = urllib2.ProxyHandler({ 27 | "http" : proxyInfo, 28 | "https" : proxyInfo, 29 | }) 30 | 31 | opener = urllib2.build_opener(proxy_handler) 32 | 33 | urllib2.install_opener(opener) 34 | 35 | #访问目标页面 36 | resp = urllib2.urlopen(Url).read() 37 | print resp 38 | 39 | -------------------------------------------------------------------------------- /Nodejs/superagent.js: -------------------------------------------------------------------------------- 1 | // 安装superagent 命令: npm install superagent 2 | // 安装superagent-proxy 命令: npm install superagent-proxy 3 | 4 | // 引入superagent 5 | let request = require('superagent') 6 | // 引入superagent-proxy 7 | require('superagent-proxy')(request) 8 | 9 | // 目标网站 10 | let targetUrl = '目标网站' 11 | 12 | // 代理服务器信息 13 | // 代理账号密码信息 如:account:password 14 | let auth = '账号:密码' 15 | // 设置代理服务器域名和端口 如:example.cn:8888 注意:此处域名不能带协议,具体的域名要依据据开通账号时分配的而定 16 | let proxy_server = '域名:端口' 17 | // 代理验证url 如:http://account:password@example.cn:8888 18 | let proxyUrl = 'http://' + auth + '@' + proxy_server 19 | 20 | // 请求目标网站 21 | request.get(targetUrl) 22 | .proxy(proxyUrl) 23 | .then(res => { 24 | console.log(res.text) 25 | }).catch(err => { 26 | console.log(err.message) 27 | }) 28 | 29 | -------------------------------------------------------------------------------- /PHP/PHPCurlDemo.php: -------------------------------------------------------------------------------- 1 | 39 | -------------------------------------------------------------------------------- /Python/PythonAioHttpDemo.py: -------------------------------------------------------------------------------- 1 | import time 2 | import asyncio 3 | from aiohttp import ClientSession, TCPConnector, BasicAuth 4 | 5 | async def fetch(url, session): 6 | proxy_auth = BasicAuth('账号', '密码') 7 | headers = {'connection': 'closed'} 8 | async with session.get(url=url, 9 | proxy="http://域名:端口", 10 | proxy_auth=proxy_auth, 11 | headers=headers) as resp: 12 | print(await resp.read()) 13 | 14 | connector = TCPConnector(limit=10) 15 | session = ClientSession(connector=connector) 16 | nums = 300 17 | url = 'https://pv.sohu.com/cityjson?ie=utf-8' 18 | tasks = [fetch(url, session) for x in range(nums)] 19 | begin = time.time() 20 | try: 21 | loop = asyncio.get_event_loop() 22 | loop.run_until_complete(asyncio.wait(tasks)) 23 | except: 24 | pass 25 | finally: 26 | end = time.time() 27 | loop.close() 28 | session.close() 29 | print('cost', end - begin, 'speed', nums / (end - begin), 'req/s') 30 | -------------------------------------------------------------------------------- /Java/JsoupDemo.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.IOException; 3 | 4 | import org.jsoup.Jsoup; 5 | 6 | public class JsoupSetProxyExample { 7 | 8 | public static void main(String[] args) { 9 | 10 | try{ 11 | 12 | //http代理服务器地址 13 | System.setProperty("http.proxyHost", "域名"); 14 | 15 | //http代理服务器端口 16 | System.setProperty("http.proxyPort", "端口"); 17 | //代理账号密码 18 | System.setProperty("https.proxyUser", "账号"); 19 | System.setProperty("https.proxyPassword", "密码"); 20 | 21 | String strText = 22 | Jsoup 23 | //.connect("https://myip.ipip.net") 24 | .connect("https://pv.sohu.com/cityjson?ie=utf-8") 25 | .userAgent("Mozilla/5.0") 26 | .timeout(10 * 1000) 27 | .get() 28 | .text(); 29 | 30 | System.out.println(strText); 31 | 32 | }catch(IOException ioe){ 33 | System.out.println("Exception: " + ioe); 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Java/HttpUrlConnectionDemo.java: -------------------------------------------------------------------------------- 1 | import java.io.ByteArrayOutputStream; 2 | import java.io.IOException; 3 | import java.io.InputStream; 4 | import java.io.OutputStream; 5 | import java.net.HttpURLConnection; 6 | import java.io.IOException; 7 | import java.net.InetSocketAddress; 8 | import java.net.Proxy; 9 | import java.net.URL; 10 | import java.io.BufferedReader; 11 | import java.io.InputStreamReader; 12 | import org.apache.commons.io.IOUtils; 13 | import java.net.*; 14 | import org.apache.commons.codec.binary.Base64; 15 | import java.net.PasswordAuthentication; 16 | 17 | class ProxyAuthenticator extends Authenticator { 18 | private String user, password; 19 | 20 | public ProxyAuthenticator(String user, String password) { 21 | this.user = user; 22 | this.password = password; 23 | } 24 | 25 | protected PasswordAuthentication getPasswordAuthentication() { 26 | return new PasswordAuthentication(user, password.toCharArray()); 27 | } 28 | } 29 | 30 | 31 | public class HttpUrlConnectionDemo { 32 | 33 | 34 | public static String requestUrl(String requestUrl) 35 | { 36 | // 代理服务器 37 | String proxyServer = "域名"; 38 | int proxyPort = 端口; 39 | // 代理隧道验证信息 40 | String proxyUser = "账号"; 41 | String proxyPass = "密码"; 42 | 43 | Authenticator.setDefault(new ProxyAuthenticator(proxyUser, proxyPass)); 44 | 45 | InetSocketAddress addr = new InetSocketAddress(proxyServer,proxyPort);//代理服务器地址,端口 46 | Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); 47 | 48 | 49 | try { 50 | URL url = new URL(requestUrl); 51 | // 设置通过代理访问目标页面 52 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy); 53 | InputStream in = conn.getInputStream(); 54 | String s = IOUtils.toString(in, "utf-8"); 55 | return s; 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | return null; 59 | } 60 | } 61 | 62 | public static void main(String[] args) { 63 | try { 64 | 65 | //访问目标url 66 | String s = requestUrl("https://pv.sohu.com/cityjson?ie=utf-8"); 67 | System.out.println("目标网站访问成功:"+s); 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /Go/GoDemo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "net/http" 8 | "net/http/httputil" 9 | "net/url" 10 | ) 11 | 12 | func main() { 13 | 14 | //creating the proxyURL 15 | proxyStr := "http://域名:端口" 16 | proxyURL, err := url.Parse(proxyStr) 17 | proxyURL.User = url.UserPassword("账号", "密码") 18 | if err != nil { 19 | log.Println(err) 20 | } 21 | 22 | 23 | 24 | 25 | //creating the URL to be loaded through the proxy 26 | urlStr := "https://pv.sohu.com/cityjson?ie=utf-8" 27 | url, err := url.Parse(urlStr) 28 | if err != nil { 29 | log.Println(err) 30 | } 31 | 32 | //adding the proxy settings to the Transport object 33 | transport := &http.Transport{ 34 | Proxy: http.ProxyURL(proxyURL), 35 | } 36 | 37 | //adding the Transport object to the http Client 38 | client := &http.Client{ 39 | Transport: transport, 40 | } 41 | 42 | //generating the HTTP GET request 43 | request, err := http.NewRequest("GET", url.String(), nil) 44 | if err != nil { 45 | log.Println(err) 46 | } 47 | 48 | //adding header for close keepalive 49 | connection := "closed" 50 | request.Header.Add("Connection", connection) 51 | 52 | //printing the request to the console 53 | dump, _ := httputil.DumpRequest(request, false) 54 | fmt.Println(string(dump)) 55 | 56 | //calling the URL 57 | response, err := client.Do(request) 58 | if err != nil { 59 | log.Println(err) 60 | } 61 | 62 | log.Println(response.StatusCode) 63 | log.Println(response.Status) 64 | //getting the response 65 | data, err := ioutil.ReadAll(response.Body) 66 | if err != nil { 67 | log.Println(err) 68 | } 69 | //printing the response 70 | log.Println(string(data)) 71 | 72 | //calling the URL 73 | response1, err := client.Do(request) 74 | if err != nil { 75 | log.Println(err) 76 | } 77 | 78 | log.Println(response1.StatusCode) 79 | log.Println(response1.Status) 80 | //getting the response 81 | data1, err := ioutil.ReadAll(response1.Body) 82 | if err != nil { 83 | log.Println(err) 84 | } 85 | //printing the response 86 | log.Println(string(data1)) 87 | } 88 | -------------------------------------------------------------------------------- /Java/JavaHttpClientDemo.java: -------------------------------------------------------------------------------- 1 | import javax.net.ssl.SSLContext; 2 | import org.apache.http.HttpHeaders; 3 | import org.apache.http.HttpHost; 4 | import org.apache.http.auth.AuthScope; 5 | import org.apache.http.auth.UsernamePasswordCredentials; 6 | import org.apache.http.client.AuthCache; 7 | import org.apache.http.client.CredentialsProvider; 8 | import org.apache.http.client.config.RequestConfig; 9 | import org.apache.http.client.methods.CloseableHttpResponse; 10 | import org.apache.http.client.methods.HttpGet; 11 | import org.apache.http.client.protocol.HttpClientContext; 12 | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 13 | import org.apache.http.conn.ssl.TrustSelfSignedStrategy; 14 | import org.apache.http.impl.auth.BasicScheme; 15 | import org.apache.http.impl.client.BasicAuthCache; 16 | import org.apache.http.impl.client.BasicCredentialsProvider; 17 | import org.apache.http.impl.client.CloseableHttpClient; 18 | import org.apache.http.impl.client.HttpClients; 19 | import org.apache.http.message.BasicHeader; 20 | import org.apache.http.ssl.SSLContexts; 21 | import org.apache.http.util.EntityUtils; 22 | 23 | public class JavaHttpClientDemo { 24 | 25 | public static void main(String[] args) throws Exception { 26 | 27 | 28 | CredentialsProvider credsProvider = new BasicCredentialsProvider(); 29 | credsProvider.setCredentials( 30 | new AuthScope("代理服务器域名", 9180), 31 | new UsernamePasswordCredentials("user", "passwd")); 32 | 33 | try (CloseableHttpClient httpclient = HttpClients.custom() 34 | .setDefaultCredentialsProvider(credsProvider) 35 | .build()) 36 | { 37 | HttpHost target = new HttpHost("pv.sohu.com", 443, "https"); 38 | HttpHost proxy = new HttpHost("代理服务器域名", 9180); 39 | 40 | AuthCache authCache = new BasicAuthCache(); 41 | 42 | BasicScheme basicAuth = new BasicScheme(); 43 | basicAuth.processChallenge( 44 | new BasicHeader(HttpHeaders.PROXY_AUTHENTICATE, 45 | "Basic realm=\"Crawlera\"")); 46 | authCache.put(proxy, basicAuth); 47 | 48 | HttpClientContext ctx = HttpClientContext.create(); 49 | ctx.setAuthCache(authCache); 50 | 51 | RequestConfig config = RequestConfig.custom() 52 | .setProxy(proxy) 53 | .build(); 54 | 55 | HttpGet httpget = new HttpGet("/cityjson?ie=utf-8"); 56 | httpget.setConfig(config); 57 | 58 | System.out.println("Executing request " + httpget.getRequestLine() + 59 | " to " + target + " via " + proxy); 60 | 61 | try (CloseableHttpResponse response = httpclient.execute( 62 | target, httpget, ctx)) 63 | { 64 | System.out.println("----------------------------------------"); 65 | System.out.println(response.getStatusLine()); 66 | System.out.println("----------------------------------------"); 67 | System.out.println(EntityUtils.toString(response.getEntity())); 68 | EntityUtils.consume(response.getEntity()); 69 | } 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /Scrapy/middlewares.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Define here the models for your spider middleware 4 | # 5 | # See documentation in: 6 | # https://doc.scrapy.org/en/latest/topics/spider-middleware.html 7 | 8 | from scrapy import signals 9 | import base64 10 | 11 | 12 | 13 | class FormoonSpiderMiddleware(object): 14 | # Not all methods need to be defined. If a method is not defined, 15 | # scrapy acts as if the spider middleware does not modify the 16 | # passed objects. 17 | 18 | @classmethod 19 | def from_crawler(cls, crawler): 20 | # This method is used by Scrapy to create your spiders. 21 | s = cls() 22 | crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) 23 | return s 24 | 25 | def process_spider_input(self, response, spider): 26 | # Called for each response that goes through the spider 27 | # middleware and into the spider. 28 | 29 | # Should return None or raise an exception. 30 | return None 31 | 32 | def process_spider_output(self, response, result, spider): 33 | # Called with the results returned from the Spider, after 34 | # it has processed the response. 35 | 36 | # Must return an iterable of Request, dict or Item objects. 37 | for i in result: 38 | yield i 39 | 40 | def process_spider_exception(self, response, exception, spider): 41 | # Called when a spider or process_spider_input() method 42 | # (from other spider middleware) raises an exception. 43 | 44 | # Should return either None or an iterable of Response, dict 45 | # or Item objects. 46 | pass 47 | 48 | def process_start_requests(self, start_requests, spider): 49 | # Called with the start requests of the spider, and works 50 | # similarly to the process_spider_output() method, except 51 | # that it doesn’t have a response associated. 52 | 53 | # Must return only requests (not items). 54 | for r in start_requests: 55 | yield r 56 | 57 | def spider_opened(self, spider): 58 | spider.logger.info('Spider opened: %s' % spider.name) 59 | 60 | 61 | class FormoonDownloaderMiddleware(object): 62 | # Not all methods need to be defined. If a method is not defined, 63 | # scrapy acts as if the downloader middleware does not modify the 64 | # passed objects. 65 | 66 | @classmethod 67 | def from_crawler(cls, crawler): 68 | # This method is used by Scrapy to create your spiders. 69 | s = cls() 70 | crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) 71 | return s 72 | 73 | def process_request(self, request, spider): 74 | # Called for each request that goes through the downloader 75 | # middleware. 76 | 77 | # Must either: 78 | # - return None: continue processing this request 79 | # - or return a Response object 80 | # - or return a Request object 81 | # - or raise IgnoreRequest: process_exception() methods of 82 | # installed downloader middleware will be called 83 | return None 84 | 85 | def process_response(self, request, response, spider): 86 | # Called with the response returned from the downloader. 87 | 88 | # Must either; 89 | # - return a Response object 90 | # - return a Request object 91 | # - or raise IgnoreRequest 92 | return response 93 | 94 | def process_exception(self, request, exception, spider): 95 | # Called when a download handler or a process_request() 96 | # (from other downloader middleware) raises an exception. 97 | 98 | # Must either: 99 | # - return None: continue processing this exception 100 | # - return a Response object: stops process_exception() chain 101 | # - return a Request object: stops process_exception() chain 102 | pass 103 | 104 | def spider_opened(self, spider): 105 | spider.logger.info('Spider opened: %s' % spider.name) 106 | 107 | class ProxyMiddleware(object): 108 | # overwrite process request 109 | def process_request(self, request, spider): 110 | # 设置代理服务器域名和端口,注意,具体的域名要依据据开通账号时分配的而定 111 | request.meta['proxy'] = "http://域名:端口" 112 | 113 | # 设置账号密码 114 | proxy_user_pass = "httuser:userpass" 115 | # setup basic authentication for the proxy 116 | # For python3 117 | encoded_user_pass = "Basic " + base64.urlsafe_b64encode(bytes((proxy_user_pass), "ascii")).decode("utf8") 118 | # For python2 119 | #encoded_user_pass = "Basic " + base64.b64encode(proxy_user_pass) 120 | 121 | request.headers['Proxy-Authorization'] = encoded_user_pass 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /Java/InstallCert.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * - Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * - Neither the name of Sun Microsystems nor the names of its 16 | * contributors may be used to endorse or promote products derived 17 | * from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | import java.io.*; 33 | import java.net.URL; 34 | 35 | import java.security.*; 36 | import java.security.cert.*; 37 | 38 | import javax.net.ssl.*; 39 | 40 | /** 41 | * 安装证书 42 | * 43 | * @author 单红宇(365384722) 44 | * @myblog http://blog.csdn.net/catoop/ 45 | * @create 2016年4月14日 46 | */ 47 | public class InstallCert { 48 | 49 | // 我们要访问的HTTPS服务,如访问 https://www.shanhy.com 50 | public static final String hostName = "ipcrs.pbccrc.org.cn"; 51 | 52 | public static void main(String[] args) throws Exception { 53 | args = new String[]{hostName}; 54 | String host; 55 | int port; 56 | char[] passphrase; 57 | if ((args.length == 1) || (args.length == 2)) { 58 | String[] c = args[0].split(":"); 59 | host = c[0]; 60 | port = (c.length == 1) ? 443 : Integer.parseInt(c[1]); 61 | String p = (args.length == 1) ? "changeit" : args[1]; 62 | passphrase = p.toCharArray(); 63 | } else { 64 | System.out.println("Usage: java InstallCert [:port] [passphrase]"); 65 | return; 66 | } 67 | 68 | File file = new File("jssecacerts"); 69 | if (file.isFile() == false) { 70 | char SEP = File.separatorChar; 71 | File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security"); 72 | file = new File(dir, "jssecacerts"); 73 | if (file.isFile() == false) { 74 | file = new File(dir, "cacerts"); 75 | } 76 | } 77 | System.out.println("Loading KeyStore " + file + "..."); 78 | InputStream in = new FileInputStream(file); 79 | KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 80 | ks.load(in, passphrase); 81 | in.close(); 82 | 83 | SSLContext context = SSLContext.getInstance("TLS"); 84 | TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 85 | tmf.init(ks); 86 | X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; 87 | SavingTrustManager tm = new SavingTrustManager(defaultTrustManager); 88 | context.init(null, new TrustManager[] { tm }, null); 89 | SSLSocketFactory factory = context.getSocketFactory(); 90 | 91 | System.out.println("Opening connection to " + host + ":" + port + "..."); 92 | SSLSocket socket = (SSLSocket) factory.createSocket(host, port); 93 | socket.setSoTimeout(10000); 94 | try { 95 | System.out.println("Starting SSL handshake..."); 96 | socket.startHandshake(); 97 | socket.close(); 98 | System.out.println(); 99 | System.out.println("No errors, certificate is already trusted"); 100 | } catch (SSLException e) { 101 | System.out.println(); 102 | e.printStackTrace(System.out); 103 | } 104 | 105 | X509Certificate[] chain = tm.chain; 106 | if (chain == null) { 107 | System.out.println("Could not obtain server certificate chain"); 108 | return; 109 | } 110 | 111 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 112 | 113 | System.out.println(); 114 | System.out.println("Server sent " + chain.length + " certificate(s):"); 115 | System.out.println(); 116 | MessageDigest sha1 = MessageDigest.getInstance("SHA1"); 117 | MessageDigest md5 = MessageDigest.getInstance("MD5"); 118 | for (int i = 0; i < chain.length; i++) { 119 | X509Certificate cert = chain[i]; 120 | System.out.println(" " + (i + 1) + " Subject " + cert.getSubjectDN()); 121 | System.out.println(" Issuer " + cert.getIssuerDN()); 122 | sha1.update(cert.getEncoded()); 123 | System.out.println(" sha1 " + toHexString(sha1.digest())); 124 | md5.update(cert.getEncoded()); 125 | System.out.println(" md5 " + toHexString(md5.digest())); 126 | System.out.println(); 127 | } 128 | 129 | System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]"); 130 | String line = reader.readLine().trim(); 131 | int k; 132 | try { 133 | k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1; 134 | } catch (NumberFormatException e) { 135 | System.out.println("KeyStore not changed"); 136 | return; 137 | } 138 | 139 | X509Certificate cert = chain[k]; 140 | String alias = host + "-" + (k + 1); 141 | ks.setCertificateEntry(alias, cert); 142 | 143 | OutputStream out = new FileOutputStream("jssecacerts"); 144 | ks.store(out, passphrase); 145 | out.close(); 146 | 147 | System.out.println(); 148 | System.out.println(cert); 149 | System.out.println(); 150 | System.out.println("Added certificate to keystore 'jssecacerts' using alias '" + alias + "'"); 151 | } 152 | 153 | private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); 154 | 155 | private static String toHexString(byte[] bytes) { 156 | StringBuilder sb = new StringBuilder(bytes.length * 3); 157 | for (int b : bytes) { 158 | b &= 0xff; 159 | sb.append(HEXDIGITS[b >> 4]); 160 | sb.append(HEXDIGITS[b & 15]); 161 | sb.append(' '); 162 | } 163 | return sb.toString(); 164 | } 165 | 166 | private static class SavingTrustManager implements X509TrustManager { 167 | 168 | private final X509TrustManager tm; 169 | private X509Certificate[] chain; 170 | 171 | SavingTrustManager(X509TrustManager tm) { 172 | this.tm = tm; 173 | } 174 | 175 | public X509Certificate[] getAcceptedIssuers() { 176 | throw new UnsupportedOperationException(); 177 | } 178 | 179 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 180 | throw new UnsupportedOperationException(); 181 | } 182 | 183 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 184 | this.chain = chain; 185 | tm.checkServerTrusted(chain, authType); 186 | } 187 | } 188 | 189 | } 190 | --------------------------------------------------------------------------------