`
410063005
  • 浏览: 179984 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Java SSLSocket的使用

 
阅读更多

1. 什么是SSLSocket

JDK文档指出,SSLSocket扩展Socket并提供使用SSL或TLS协议的安全套接字。

这种套接字是正常的流套接字,但是它们在基础网络传输协议(如TCP)上添加了安全保护层。

具体安全方面的讨论见下一篇。本篇重点关注SSLSocket及相关几个类的使用。

 

2. SSLSocket和相关类

SSLSocket来自jsse(Java Secure Socket Extension)。

 

 

(1)SSLContext: 此类的实例表示安全套接字协议的实现, 它是SSLSocketFactory、SSLServerSocketFactory和SSLEngine的工厂。

 

(2)SSLSocket: 扩展自Socket

 

(3)SSLServerSocket: 扩展自ServerSocket

 

(4)SSLSocketFactory: 抽象类,扩展自SocketFactory, SSLSocket的工厂

 

(5)SSLServerSocketFactory: 抽象类,扩展自ServerSocketFactory, SSLServerSocket的工厂

 

(6)KeyStore: 表示密钥和证书的存储设施

 

(7)KeyManager: 接口,JSSE密钥管理器

 

(8)TrustManager: 接口,信任管理器(?翻译得很拗口)

 

(9)X590TrustedManager: TrustManager的子接口,管理X509证书,验证远程安全套接字

 

3. SSLContext的使用

 

 

	public static void main(String[] args) throws Exception {
		X509TrustManager x509m = new X509TrustManager() {

			@Override
			public X509Certificate[] getAcceptedIssuers() {
				return null;
			}

			@Override
			public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
			}

			@Override
			public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
			}
		};
		// 获取一个SSLContext实例
		SSLContext s = SSLContext.getInstance("SSL");
		// 初始化SSLContext实例
		s.init(null, new TrustManager[] { x509m },
				new java.security.SecureRandom());
		// 打印这个SSLContext实例使用的协议
		System.out.println("缺省安全套接字使用的协议: " + s.getProtocol());
		// 获取SSLContext实例相关的SSLEngine
		SSLEngine e = s.createSSLEngine();
		System.out
				.println("支持的协议: " + Arrays.asList(e.getSupportedProtocols()));
		System.out.println("启用的协议: " + Arrays.asList(e.getEnabledProtocols()));
		System.out.println("支持的加密套件: "
				+ Arrays.asList(e.getSupportedCipherSuites()));
		System.out.println("启用的加密套件: "
				+ Arrays.asList(e.getEnabledCipherSuites()));
	}

 运行结果如下:

 

 

SSLContext.getProtocol(): 返回当前SSLContext对象的协议名称

SSLContext.init():  初始化当前SSLContext对象。 三个参数均可以为null。 详见JDK文档。

SSLEngine.getSupportedProtocols()等几个方法可以返回些 Engine上支持/已启用的协议、支持/已启用的加密套件

 

4. SSLSocket和SSLServerSocket的使用

这两个类的用法跟Socket/ServerSocket的用法比较类似。看下面的例子(主要为了验证SSLSocket的用法 ,I/O和多线程处理比较随意)

 

4.1 SSLServerSocket

(1)新建一个SSLServerSocket,并开始监听来自客户端的连接

 

 

	// 抛出异常
	// javax.net.ssl.SSLException: No available certificate or key corresponds
	// to the SSL cipher suites which are enabled.
	public static void notOk() throws IOException {
		SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory
				.getDefault();
		SSLServerSocket server = (SSLServerSocket) factory
				.createServerSocket(10000);
		System.out.println("ok");
		server.accept();
	}

 server.accept()处抛出异常, 提示缺少证书。与ServerSocket不同, SSLServerSocket需要证书来进行安全验证。

 

使用keytool工具生成一个证书。 步骤如下, 得到一个名为cmkey的证书文件

 

 

(2)重新完善上面的代码。 主要增加两个功能: 使用名为cmkey的证书初始化SSLContext, echo客户端的消息。 代码如下

 

 

	// 启动一个ssl server socket
	// 配置了证书, 所以不会抛出异常
	public static void sslSocketServer() throws Exception {

		// key store相关信息
		String keyName = "cmkey";
		char[] keyStorePwd = "123456".toCharArray();
		char[] keyPwd = "123456".toCharArray();
		KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

		// 装载当前目录下的key store. 可用jdk中的keytool工具生成keystore
		InputStream in = null;
		keyStore.load(in = Test2.class.getClassLoader().getResourceAsStream(
				keyName), keyPwd);
		in.close();

		// 初始化key manager factory
		KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
				.getDefaultAlgorithm());
		kmf.init(keyStore, keyPwd);

		// 初始化ssl context
		SSLContext context = SSLContext.getInstance("SSL");
		context.init(kmf.getKeyManagers(),
				new TrustManager[] { new MyX509TrustManager() },
				new SecureRandom());

		// 监听和接收客户端连接
		SSLServerSocketFactory factory = context.getServerSocketFactory();
		SSLServerSocket server = (SSLServerSocket) factory
				.createServerSocket(10002);
		System.out.println("ok");
		Socket client = server.accept();
		System.out.println(client.getRemoteSocketAddress());

		// 向客户端发送接收到的字节序列
		OutputStream output = client.getOutputStream();

		// 当一个普通 socket 连接上来, 这里会抛出异常
		// Exception in thread "main" javax.net.ssl.SSLException: Unrecognized
		// SSL message, plaintext connection?
		InputStream input = client.getInputStream();
		byte[] buf = new byte[1024];
		int len = input.read(buf);
		System.out.println("received: " + new String(buf, 0, len));
		output.write(buf, 0, len);
		output.flush();
		output.close();
		input.close();

		// 关闭socket连接
		client.close();
		server.close();
	}
 

4.2 SSLSocket

(1)我们先使用一个普通的Socket尝试连接服务器端

 

	// 通过socket连接服务器
	public static void socket() throws UnknownHostException, IOException {
		Socket s = new Socket("localhost", 10002);
		System.out.println(s);
		System.out.println("ok");

		OutputStream output = s.getOutputStream();
		InputStream input = s.getInputStream();

		output.write("alert".getBytes());
		System.out.println("sent: alert");
		output.flush();

		byte[] buf = new byte[1024];
		int len = input.read(buf);
		System.out.println("received:" + new String(buf, 0, len));
	}

 结果客户端和服务器端都出错。 客户端的错误是接收到乱码。 


服务器则抛出异常

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

 

(2)改成SSLSocket, 但是不使用证书。客户端抛出sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

 

 

	// 不使用证书, 通过ssl socket连接服务器
	// 抛出异常, 提示找不到证书
	public static void sslSocket() throws UnknownHostException, IOException {
		SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory
				.getDefault();
		SSLSocket s = (SSLSocket) factory.createSocket("localhost", 10002);
		System.out.println("ok");

		OutputStream output = s.getOutputStream();
		InputStream input = s.getInputStream();

		output.write("alert".getBytes());
		System.out.println("sent: alert");
		output.flush();

		byte[] buf = new byte[1024];
		int len = input.read(buf);
		System.out.println("received:" + new String(buf, 0, len));
	}

程序客户在不持有证书的情况下直接进行连接,服务器端会产生运行时异常javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown,不允许进行连接。 我们可以指定像下面这样执行客户端,服务器端可以成功echo客户端的发出的字符串"alert"

 

 java  -Djavax.net.ssl.trustStore=cmkey Client

 

这里的cmkey即前面生成的证书文件。

 

(3)改成SSLSocket, 对SSLContext进行如下初始化。

 

	public static void sslSocket2() throws Exception {
		SSLContext context = SSLContext.getInstance("SSL");
                // 初始化
		context.init(null,
				new TrustManager[] { new Test2.MyX509TrustManager() },
				new SecureRandom());
		SSLSocketFactory factory = context.getSocketFactory();
		SSLSocket s = (SSLSocket) factory.createSocket("localhost", 10002);
		System.out.println("ok");

		OutputStream output = s.getOutputStream();
		InputStream input = s.getInputStream();

		output.write("alert".getBytes());
		System.out.println("sent: alert");
		output.flush();

		byte[] buf = new byte[1024];
		int len = input.read(buf);
		System.out.println("received:" + new String(buf, 0, len));
	}

 服务器端可以成功echo客户端的发出的字符串"alert"。 完整代码见附件。

 

 

参考  http://java.ccidnet.com/art/3737/20060808/789375_1.html

 http://blog.csdn.net/scliu0718/article/details/7198889

http://www.iteye.com/topic/1114800

  • 大小: 63.6 KB
  • 大小: 33 KB
  • 大小: 22.8 KB
  • 大小: 3.7 KB
  • src.rar (3.4 KB)
  • 下载次数: 571
分享到:
评论
9 楼 beiizl 2017-05-02  
用了博主的方法和代码,不同证书居然可以正常通讯?
8 楼 SHANGLIJAVA 2016-07-29  
sorry,运行时没看清。博主的代码确实没问题。。。
7 楼 SHANGLIJAVA 2016-07-29  
YoungeeOne 写道
最后一个为什么初始化一个空的证书,也能连上?

亲测,在client里没用keystore初始化context,读不出数据,因此要加上。
String keyName = "cmkey";
		char[] keyStorePwd = "123456".toCharArray();
		char[] keyPwd = "123456".toCharArray();
		KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

		// 装载当前目录下的key store. 可用jdk中的keytool工具生成keystore
		InputStream in = null;
		keyStore.load(in = ServerSsl.class.getClassLoader()
				.getResourceAsStream(keyName), keyPwd);
		in.close();

		// 初始化key manager factory
		KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
				.getDefaultAlgorithm());
		kmf.init(keyStore, keyPwd);
		
		
		SSLContext context = SSLContext.getInstance("SSL");
		context.init(kmf.getKeyManagers(),
				new TrustManager[] { new ServerSsl.MyX509TrustManager() },
				new SecureRandom());
6 楼 q979713444 2016-06-22  
那这个的心跳怎么弄呢
5 楼 zxjlwt 2015-09-01  
学习了。

http://surenpi.com
4 楼 天使ai美丽 2015-06-15  
非常好 mark了
3 楼 繁星水 2015-02-26  
好,非常好
2 楼 YoungeeOne 2014-12-19  
最后一个为什么初始化一个空的证书,也能连上?
1 楼 sundhu 2014-09-02  
very good 

相关推荐

    数学建模学习资料 神经网络算法 参考资料-Matlab 共26页.pptx

    数学建模学习资料 神经网络算法 参考资料-Matlab 共26页.pptx

    happybirthday2 升级版生日祝福密码0000(7).zip

    happybirthday2 升级版生日祝福密码0000(7).zip

    ssm框架Java项目源码-基于web技术的税务门户网站的实现+vue毕设-大作业.zip

    本项目是一个基于SSM框架的税务门户网站实现,结合了Vue技术,旨在提供一个全面的税务信息管理平台。该项目主要功能包括税务信息查询、税务申报、税务政策浏览及用户管理等多个模块。通过这些功能,用户可以方便地查询和管理税务相关的各类信息,同时也能及时了解最新的税务政策和规定。 项目采用SSM框架,即Spring、Spring MVC和MyBatis,这三者的结合为项目提供了强大的后端支持,确保了数据的安全性和系统的稳定性。前端则采用Vue.js框架,以其高效的数据绑定和组件化开发模式,提升了用户界面的响应速度和用户体验。 开发此项目的目的不仅是为了满足计算机相关专业学生在毕业设计中的实际需求,更是为了帮助Java学习者通过实战练习,深入理解并掌握SSM框架的应用,从而在实际工作中能够更好地运用这些技术。

    php7.4.33镜像7z压缩包

    php7.4.33镜像7z压缩包

    ssm框架Java项目源码-基于java的珠宝购物网站系统的建设+jsp毕设-大作业.zip

    本项目是一个基于Java的珠宝购物网站系统,采用SSM框架进行开发,旨在为计算机相关专业学生提供一个实践平台,同时也适合Java学习者进行实战练习。项目的核心功能涵盖商品展示、用户注册登录、购物车管理、订单处理和支付系统等。通过这一系统,用户可以浏览各类珠宝商品,包括详细的商品描述、高清图片和价格信息,同时能够方便地添加商品至购物车,并进行结算和支付操作。 在技术实现方面,项目运用了Spring、Spring MVC和MyBatis三大框架,确保系统的稳定性和扩展性。Spring负责业务逻辑层,提供依赖注入和面向切面编程的支持;Spring MVC则处理Web层的请求和响应,实现MVC设计模式;MyBatis作为持久层框架,简化了数据库操作。 此外,项目采用JSP技术进行前端页面展示,结合HTML、CSS和JavaScript等技术,为用户提供友好的交互界面。

    基于java的高校大学生党建系统设计与实现.docx

    基于java的高校大学生党建系统设计与实现.docx

    毕设源码-python-django疫情数据可视化分析系统(论文+PPT)-期末大作业+说明文档.rar

    本项目是一个基于Python-Django框架开发的疫情数据可视化分析系统,旨在为计算机相关专业的学生提供一个实践平台,同时也适用于需要进行项目实战练习的同学。项目集成了疫情数据的收集、处理、分析和可视化功能,为用户提供了一个直观、高效的数据分析环境。 在功能方面,系统能够自动抓取最新的疫情数据,包括确诊、疑似、治愈和死亡人数等关键指标。数据处理模块则负责清洗和整理这些数据,以确保分析的准确性。分析模块采用了多种统计方法和机器学习算法,以揭示疫情的发展趋势和潜在模式。可视化模块则通过图表和地图等形式,直观地展示了分析结果,便于用户理解和分享。 项目的开发框架选择了Django,这是一个高级Python Web框架,它鼓励快速开发和清晰、务实的设计。Django的强大功能和灵活性,使得项目能够快速响应需求变化,同时保证了系统的稳定性和安全性。

    果树领养计划.docx

    果树领养计划.docx

    java毕设项目之java基于云平台的信息安全攻防实训平台(源码+说明文档+mysql).zip

    环境说明:开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat 开发软件:eclipse/myeclipse/idea Maven包:Maven 浏览器:谷歌浏览器。 项目均可完美运行 基于Java的云平台信息安全攻防实训平台提供了以下核心功能: 1. **实训课程与项目**:平台提供了丰富多样的实训课程和项目,覆盖网络安全基础知识、漏洞挖掘与利用、渗透测试技术、安全防护策略等多个领域。 2. **在线学习模块**:学员可以通过在线学习模块观看教学视频、阅读文档资料,系统地学习信息安全知识。 3. **虚拟实验室环境**:平台提供虚拟实验室环境,学员可以在模拟的真实网络场景中进行攻防演练,包括漏洞扫描、攻击测试和防御措施的学习。 4. **教学管理功能**:教师可以创建和管理课程内容,制定教学计划,布置实训作业和考试任务。 5. **监控和统计功能**:教师可以实时了解学员的学习进度、实践操作情况和考试成绩,进行有针对性的指导和辅导。 6. **平台管理功能**:管理员负责用户管理、资源分配、系统安全维护等,确保平台稳定运行和实训环境的安全性。 7. **实时监控和评估**:系统具备实时监控和评估功能,能够及时反馈学生的操作情况和学习效果。 8. **用户认证和授权机制**:平台采用了严格的用户认证和授权机制,确保数据的安全性和保密性。 这些功能共同构建了一个功能丰富、操作便捷的实训环境,旨在提升学员的信息安全技能,为信息安全领域的发展输送专业人才。

    基于GrampusFramework的轻量级单体RBAC权限管理系统.zip

    基于GrampusFramework的轻量级单体RBAC权限管理系统

    软考(中级-软件设计师)知识点汇总与解析

    内容概要:本文档全面整理了软考(中级-软件设计师)的关键知识点,涵盖了计算复杂度、网络协议、数据结构、编程语言、数据库理论、软件测试、编译原理、设计模式、安全协议等多个方面的内容。具体涉及环路复杂度计算、SSH协议、数据字典与数据流图、对象的状态与数字签名、编程语言分类、海明码、著作权法、物理层与数据链路层设备、归纳法与演绎法、模块间耦合、能力成熟度模型集成、配置管理与风险管理、数据库关系范式、内存技术、计算机网络端口、路由协议、排序算法、中间代码、软件测试类型、编译器各阶段任务、设计模式、耦合与内聚、计算机病毒种类等。 适用人群:备考软考(中级-软件设计师)的技术人员,尤其是有一定工作经验但希望进一步提升自身技能和知识的IT从业人员。 使用场景及目标:帮助考生系统梳理考试重点,理解和掌握软件设计师应具备的专业知识和技术。适合考前复习和巩固基础知识。文档还可以作为参考资料,用于日常工作中遇到相关问题时查阅。 其他说明:本文档不仅提供了丰富的知识点,还附带了一些关键术语的定义和详细的解释,确保读者能够全面理解相关内容。建议在复习过程中结合实际案例进行练习,加深理解。

    数学建模学习资料 神经网络算法 Hopfield网络 共58页.pptx

    数学建模学习资料 神经网络算法 Hopfield网络 共58页.pptx

    工作寻(JobHunter)是一款招聘信息整合的网站,目前固定的模板有拉勾网,中华英才网,前程无忧。工作寻可以在线通过关.zip

    工作寻(JobHunter)是一款招聘信息整合的网站,目前固定的模板有拉勾网,中华英才网,前程无忧。工作寻可以在线通过关

    毕设源码-基于python协同过滤的音乐推荐系统的设计与实现_joqt--论文-期末大作业+说明文档.rar

    本项目是基于Python实现的协同过滤音乐推荐系统,旨在为计算机相关专业学生提供一个完整的毕设实战案例。项目以协同过滤算法为核心,通过分析用户历史行为数据,为用户推荐符合其兴趣偏好的音乐。 主要功能包括用户兴趣建模、音乐推荐生成以及用户反馈机制。系统能够实时捕捉用户听歌行为,动态更新用户兴趣模型,从而更精准地推送个性化音乐推荐。同时,系统设计了友好的用户界面,使用户能够方便地获取推荐音乐,并通过反馈机制不断完善推荐算法。 在技术框架方面,项目采用了Python编程语言,借助scikit-learn等机器学习库实现协同过滤算法,并结合Flask框架搭建了Web服务,确保了系统的性能和稳定性。此项目的开发,不仅能够帮助学生深入理解协同过滤算法及音乐推荐系统的工作原理,还能提升其软件开发和项目管理能力。

    微型餐饮补正备案材料通知书.docx

    微型餐饮补正备案材料通知书.docx

    食品生产许可质量跟踪监督建议书.docx

    食品生产许可质量跟踪监督建议书.docx

    基于django的音乐推荐系统.zip

    基于django的音乐推荐系统.zip

    如果让某人推荐Python技术书,请让他看这个列表.zip

    如果让某人推荐Python技术书,请让他看这个列表很棒的 Python 书籍如果让某人推荐Python技术书,请让他看这个列表前言好的技术书籍可以帮助我们快速成长,大部分人新生儿或者少部分受益于经典的技术书籍。在「Python开发者」微信公号后台,我们经常能收到帮忙推荐书籍的消息。此类问题在@Python开发者微博和伯乐在线的Python小组讨论中也绝非耳熟能详。 7月3日,伯乐在线在「Python开发者」微信公号发起了一个讨论(注PC端无法看到大家的评论,需要关注微信公号后,从微信公号才可以看到),通过这个讨论话题,在评论中分享对自己有帮助的大量Python技术书籍。 (Python开发者)入门《Head First Python》+入门级+微信49票+豆瓣评分9.5推荐语**66**浅显易懂,编排的顺序特别,有大量插图、对话,感觉枯燥古心通熟易懂,大量の图片,不会觉得枯燥,是一本不错的入门书《集体智慧编程》+入门级+微信123票+豆瓣评分 9.0推荐语**Mèrçurý**以实例具体的方式来展示Python的编程技巧,受益良多《Py

    基于java的博客系统设计与实现.docx

    基于java的博客系统设计与实现.docx

    建设工程基本建设程序检查表.docx

    建设工程基本建设程序检查表.docx

Global site tag (gtag.js) - Google Analytics