Https加密的实现

工作需要,要将原来的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的学习过程觉得有价值的资料,希望对看到的人有帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值