使用https访问http/https通信协议,需要哪些配置文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用https访问http/https通信协议,需要哪些配置文件相关的知识,希望对你有一定的参考价值。

项目里需要访问其他接口,通过http/https协议。我们一般是用HttpClient类来实现具体的http/https协议接口的调用。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=http://www.xxx.com/xxx;

// Init a HttpMethod
HttpMethod get = new GetMethod(url);
get.setDoAuthentication(true);
get.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));

// Call http interface
try
client.executeMethod(get);

// Handle the response from http interface
InputStream in = get.getResponseBodyAsStream();
SAXReader reader = new SAXReader();
Document doc = reader.read(in);
finally
// Release the http connection
get.releaseConnection();


以上代码在通过普通的http协议是没有问题的,但如果是https协议的话,就会有证书文件的要求了。一般情况下,是这样去做的。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=https://www.xxx.com/xxx;

if (url.startsWith("https:"))
System.setProperty("javax.net.ssl.trustStore", "/.sis.cer");
System.setProperty("javax.net.ssl.trustStorePassword", "public");


于是,这里就需要事先生成一个.sis.cer的文件,生成这个文件的方法一般是先通过浏览器访问https://,导出证书文件,再用JAVA keytool command 生成证书

# $JAVA_HOME/bin/keytool -import -file sis.cer -keystore .sis.cer

但这样做,一比较麻烦,二来证书也有有效期,过了有效期之后,又需要重新生成一次证书。如果能够避开生成证书文件的方式来使用https的话,就比较好了。

还好,在最近的项目里,我们终于找到了方法。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=https://www.xxx.com/xxx;

if (url.startsWith("https:"))
this.supportSSL(url, client);


用到了supportSSL(url, client)这个方法,看看这个方法是如何实现的。

private void supportSSL(String url, HttpClient client)
if(StringUtils.isBlank(url))
return;

String siteUrl = StringUtils.lowerCase(url);
if (!(siteUrl.startsWith("https")))
return;


try
setSSLProtocol(siteUrl, client);
catch (Exception e)
logger.error("setProtocol error ", e);

Security.setProperty( "ssl.SocketFactory.provider",
"com.tool.util.DummySSLSocketFactory");


private static void setSSLProtocol(String strUrl, HttpClient client) throws Exception

URL url = new URL(strUrl);
String host = url.getHost();
int port = url.getPort();

if (port <= 0)
port = 443;

ProtocolSocketFactory factory = new SSLSocketFactory();
Protocol authhttps = new Protocol("https", factory, port);
Protocol.registerProtocol("https", authhttps);
// set https protocol
client.getHostConfiguration().setHost(host, port, authhttps);


在supportSSL方法里,调用了Security.setProperty( "ssl.SocketFactory.provider",
"com.tool.util.DummySSLSocketFactory");
那么这个com.tool.util.DummySSLSocketFactory是这样的:
访问https 资源时,让httpclient接受所有ssl证书,在weblogic等容器中很有用
代码如下:
1. import java.io.IOException;
2. import java.net.InetAddress;
3. import java.net.InetSocketAddress;
4. import java.net.Socket;
5. import java.net.SocketAddress;
6. import java.net.UnknownHostException;
7. import java.security.KeyManagementException;
8. import java.security.NoSuchAlgorithmException;
9. import java.security.cert.CertificateException;
10. import java.security.cert.X509Certificate;
11.
12. import javax.net.SocketFactory;
13. import javax.net.ssl.SSLContext;
14. import javax.net.ssl.TrustManager;
15. import javax.net.ssl.X509TrustManager;
16.
17. import org.apache.commons.httpclient.ConnectTimeoutException;
18. import org.apache.commons.httpclient.params.HttpConnectionParams;
19. import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
20.
21. public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory
22. static
23. System.out.println(">>>>in MySecureProtocolSocketFactory>>");
24.
25. private SSLContext sslcontext = null;
26.
27. private SSLContext createSSLContext()
28. SSLContext sslcontext=null;
29. try
30. sslcontext = SSLContext.getInstance("SSL");
31. sslcontext.init(null, new TrustManager[]new TrustAnyTrustManager(), new java.security.SecureRandom());
32. catch (NoSuchAlgorithmException e)
33. e.printStackTrace();
34. catch (KeyManagementException e)
35. e.printStackTrace();
36.
37. return sslcontext;
38.
39.
40. private SSLContext getSSLContext()
41. if (this.sslcontext == null)
42. this.sslcontext = createSSLContext();
43.
44. return this.sslcontext;
45.
46.
47. public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
48. throws IOException, UnknownHostException
49. return getSSLContext().getSocketFactory().createSocket(
50. socket,
51. host,
52. port,
53. autoClose
54. );
55.
56.
57. public Socket createSocket(String host, int port) throws IOException,
58. UnknownHostException
59. return getSSLContext().getSocketFactory().createSocket(
60. host,
61. port
62. );
63.
64.
65.
66. public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
67. throws IOException, UnknownHostException
68. return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
69.
70.
71. public Socket createSocket(String host, int port, InetAddress localAddress,
72. int localPort, HttpConnectionParams params) throws IOException,
73. UnknownHostException, ConnectTimeoutException
74. if (params == null)
75. throw new IllegalArgumentException("Parameters may not be null");
76.
77. int timeout = params.getConnectionTimeout();
78. SocketFactory socketfactory = getSSLContext().getSocketFactory();
79. if (timeout == 0)
80. return socketfactory.createSocket(host, port, localAddress, localPort);
81. else
82. Socket socket = socketfactory.createSocket();
83. SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
84. SocketAddress remoteaddr = new InetSocketAddress(host, port);
85. socket.bind(localaddr);
86. socket.connect(remoteaddr, timeout);
87. return socket;
88.
89.
90.
91. //自定义私有类
92. private static class TrustAnyTrustManager implements X509TrustManager
93.
94. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
95.
96.
97. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
98.
99.
100. public X509Certificate[] getAcceptedIssuers()
101. return new X509Certificate[];
102.
103.
104.
105.

public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory
static
System.out.println(">>>>in MySecureProtocolSocketFactory>>");

private SSLContext sslcontext = null;

private SSLContext createSSLContext()
SSLContext sslcontext=null;
try
sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(null, new TrustManager[]new TrustAnyTrustManager(), new java.security.SecureRandom());
catch (NoSuchAlgorithmException e)
e.printStackTrace();
catch (KeyManagementException e)
e.printStackTrace();

return sslcontext;


private SSLContext getSSLContext()
if (this.sslcontext == null)
this.sslcontext = createSSLContext();

return this.sslcontext;


public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException
return getSSLContext().getSocketFactory().createSocket(
socket,
host,
port,
autoClose
);


public Socket createSocket(String host, int port) throws IOException,
UnknownHostException
return getSSLContext().getSocketFactory().createSocket(
host,
port

然后按如下方式使用HttpClient
Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);
Protocol.registerProtocol("https", myhttps);
HttpClient httpclient=new HttpClient();
参考技术A CA证书就是文件:youdomain.crt和私钥文件youdomain.key
打开nginx安装目录下conf目录中的nginx.conf文件,找到被注释掉的server 配置,进行修改:
server
listen 443 ssl;
server_name www.yourdomian.com;
ssl on;
ssl_certificate /usr/local/nginx/conf/youdomain.crt; #证书公钥
ssl_certificate_key /usr/local/nginx/conf/youdomain.key; #证书私钥
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH:AESGCM:HIGH:!RC4:!DH:!MD5:!3DES:!aNULL:!eNULL;
ssl_prefer_server_ciphers on;
location /
root html;
index index.html index.htm;


把服务器证书youdomain.crt和私钥youdomain.key上传到配置文件指向的目录/usr/local/nginx/conf/(具体文件路径可以自行指定)
保存退出,并重启nginx配置nginx -s reload后通过https方式访问您的站点,测试站点证书的安装配置。

linux设置http/https proxy及忽略proxy的方法

一,场景:

有些linux服务器处于内网,并且没有公网ip,故要想与外网进行http/https通信只能通过nat或者加proxy的方式。nat服务器有网段的限制,而http/https proxy代理则没有,使用起来也方便。但是,使用http/https proxy的时候遇见两个问题:

1,本机去访问一个没有域名解析但是绑定hosts文件的域名的时候,导致访问失败

2,php-fpm中跑的php代码访问外网有域名解析的接口,访问失败


linux系统设置http/https proxy的方法,在/etc/bashrc或者/etc/profile中添加如下环境变量:

export http_proxy=http://1.1.1.1:8082
export https_proxy=http://1.1.1.1:8082



二,问题原因

1,应该是由于环境变量的优先级别高于/etc/hosts文件,导致本机去访问一个没有域名解析但是绑定hosts文件的域名的时候仍然走http/https代理,而代理server访问不到要指定的域名从而导致访问失败。

2,php-fpm默认没有加载到系统的http/https proxy的环境变量设置,需要修改php-fpm的配置来解决问题。



三,问题解决

1,对那些没有域名解析通过绑定hosts文件来访问的域名,不让其走http/https代理

在/etc/bashrc或者/etc/profile中添加如下环境变量:

export no_proxy='a.test.com,127.0.0.1,2.2.2.2'

2,添加php-fpm关于env的如下配置,然后重启php-fpm即可:

env[http_proxy] = "http_proxy=http://1.1.1.1:8082" 
env[https_proxy] = "https_proxy=http://1.1.1.1:8082"
env[no_proxy] = "a.test.com,127.0.0.1,2.2.2.2"



四,扩展

1,用过的http/https proxy软件:

nginx

tinyproxy(简单好用,支持http/https协议)











以上是关于使用https访问http/https通信协议,需要哪些配置文件的主要内容,如果未能解决你的问题,请参考以下文章

HTTP、HTTPS、SSL/TLS概述

nginx配置https访问

确保web安全的https确认访问用户身份的认证(第七章第八章)

tomcat8配置https协议访问

Https协议

HTTP(七.HTTPS)