您的位置:首页 > 理论基础 > 计算机网络

Https加密的实现

2017-09-28 17:17 190 查看
工作需要,要将原来的http连接改成https连接。

改成https连接首先需要服务器支持,服务器 支持https连接客户端才能连接成功。

具体https原理可以参考下面这几个连接

1. java官网对https加密连接的解释
http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#SecureConnSample
2. 官网指向的例子地址
http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/samples/index.html
3. apache的地址
http://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/connmgmt.html#d5e449
4. apache例子地址
http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java
5. 博客中说的不错的地址
http://blog.csdn.net/kobejayandy/article/details/52433660 http://blog.csdn.net/dtlscsl/article/details/50118225 http://blog.csdn.net/llwszjj/article/details/36868177 http://blog.csdn.net/chw1989/article/details/7584995 http://410063005.iteye.com/blog/1751243 http://blog.csdn.net/rongyongfeikai2/article/details/41659353/
6.加密相关术语的官方解释
http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext
上面这些都是我在了解java开发https连接服务器觉得有用的链接,前4个都是英文的,这个最权威了,不过,对英文不好的人就难度有些大,

第5个都是相关博客总结的,可以帮助大家理解。

我在学习的过程写的代码:

其实是我抄的: 

代码来源是 http://fishhappy365.iteye.com/blog/963876

首先是服务器端的:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;

/*
* 打开命令行输入   keytool -genkey -keystore SSLKey -keyalg rsa -alias SSL
* 第一个参数是要生成的证书的名字,第二个参数是证书的别名。rsa指明了我们使用的加密方法。
* 系统会要求输入证书发放者的信息,逐项输入即可。
*/
public class Main006_SSLServer {

static int port = 8456; // 系统将要监听的端口号
static SSLServerSocket server;

/*
* 构造函数
*/
public Main006_SSLServer() {}

/*
* @param port 监听的端口号
*
* @return 返回一个SSLServerSocket对象
*/
private static SSLServerSocket getServerSocket(int thePort) {
SSLServerSocket s = null;
try {
String key = "C:/rsatemp/SSLKey"; // 证书的位置

char keyStorePass[] = "123456".toCharArray(); // 证书密码(生成证书时输入的)

char keyPassword[] = "123456".toCharArray(); // 证书别称所使用的主要密码 (生成证书时输入的)

KeyStore ks = KeyStore.getInstance("JKS"); // 创建JKS密钥库

ks.load(new FileInputStream(key), keyStorePass);

// 创建管理JKS密钥库的X.509密钥管理器
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

kmf.init(ks, keyPassword);

// 构造SSL环境,指定SSL版本为3.0,也可以使用TLSv1,但是SSLv3更加常用。
SSLContext sslContext = SSLContext.getInstance("TLSv1");

/*
* 初始化SSL环境。第二个参数是告诉JSSE使用的可信任证书的来源,
* 设置为null是从javax.net.ssl.trustStore中获得证书。
* 第三个参数是JSSE生成的随机数,这个参数将影响系统的安全性, 设置为null是个好选择,可以保证JSSE的安全性。
*/
sslContext.init(kmf.getKeyManagers(), null, null);

// 根据上面配置的SSL上下文来产生SSLServerSocketFactory,与通常的产生方法不同
SSLServerSocketFactory factory = sslContext.getServerSocketFactory();

s = (SSLServerSocket) factory.createServerSocket(thePort);

} catch (Exception e) {
System.out.println(e);
}
return (s);
}

public static void main(String args[]) {
try {
server = getServerSocket(port);
System.out.println("在" + port + "端口等待连接...");

while (true) {
SSLSocket socket = (SSLSocket) server.accept();

// 将得到的socket交给CreateThread对象处理,主线程继续监听
new CreateThread(socket);
}
} catch (Exception e) {
System.out.println("main方法错误80:" + e);
}
}

}

/*
* 内部类,获得主线程的socket连接,生成子线程来处理
*/

class CreateThread extends Thread {
static BufferedReader in;
static PrintWriter out;
static Socket s;

/*
* 构造函数,获得socket连接,初始化in和out对象
*/
public CreateThread(Socket socket) {
try {
s = socket;

out = new PrintWriter(s.getOutputStream(), true);

in = new BufferedReader(new InputStreamReader(s.getInputStream(), "gb2312"));

this.start(); // 开新线程执行run方法

} catch (Exception e) {
System.out.println(e);
}
}

/*
* 线程方法,处理socket传递过来的数据
*/
public void run() {
try {
String msg = in.readLine();
System.out.println(msg);
s.close();
} catch (Exception e) {
System.out.println(e);
}
}
}


客户端的代码:

//把证书拷贝到java.home下/lib/security目录下,名字SSLKey改为jssecacerts,然后可以直接执行客户端:
//http://hi.baidu.com/sunjoe/blog/item/629daa3ef802edff828b13e6.html
import java.io.PrintWriter;
import java.net.Socket;
import javax.net.ssl.SSLSocketFactory;
public class Main006_SSLClient {
static int port = 8456;

public static void main(String args[]) {
try {
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory
.getDefault();

Socket s = factory.createSocket("127.0.0.1", port);

PrintWriter out = new PrintWriter(s.getOutputStream(), true);
out.println("Hello ren zha");
out.close();
s.close();
} catch (Exception e) {
System.out.println(e);
}
}

}


下面是我使用apache的httpClient模拟客户端请求的代码

package com.chinasofti.vtmsln.httpclient.bean;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class httpsClientTest {

public static void main(String[] args) throws Exception {
X509TrustManager x509TrustManager = new X509TrustManager(){
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
};

SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{x509TrustManager}, null);

SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(sslContext,
new String[] { "TLSv1" },
null,
NoopHostnameVerifier.INSTANCE);
/*CloseableHttpClient httpClient =  HttpClients.custom()
.setSSLHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
.setSSLSocketFactory(ssf).build();*/
CloseableHttpClient httpClient = new HttpClientFactoryBean().getObject();
HttpPost httppost = new HttpPost("https://www.cctv.com");
StringBody userPwd = new StringBody("password", ContentType.TEXT_PLAIN);
StringBody userId = new StringBody("monitor01", ContentType.TEXT_PLAIN);
StringBody userType = new StringBody("user", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("userPwd", userPwd).addPart("userId", userId).addPart("userType", userType)
.build();
httppost.setEntity(reqEntity);

httpClient.execute(httppost);

}

}


当然,报错也会有

关于这个报错


Received
fatal alert: handshake_failure through SSLHandshakeException

下面的地址解释的比较详细:
https://stackoverflow.com/questions/6353849/received-fatal-alert-handshake-failure-through-sslhandshakeexception
以上就是我对https的学习过程觉得有价值的资料,希望对看到的人有帮助。

a899
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: