在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端之间Socket交互
Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库
服务端:
- public class SSLServer {
- private static final int SERVER_PORT = 50030;
- private static final String SERVER_KEY_PASSWORD = "123456";
- private static final String SERVER_AGREEMENT = "TLS";//使用协议
- private static final String SERVER_KEY_MANAGER = "SunX509";//密钥管理器
- private static final String SERVER_KEY_KEYSTORE = "JKS";//密库,这里用的是Java自带密库
- private static final String SERVER_KEYSTORE_PATH = "src/data/kserver.keystore";//密库路径
- private SSLServerSocket serverSocket;
- public static void main(String[] args) {
- SSLServer server = new SSLServer();
- server.init();
- server.start();
- }
- //由于该程序不是演示Socket监听,所以简单采用单线程形式,并且仅仅接受客户端的消息,并且返回客户端指定消息
- public void start() {
- if (serverSocket == null) {
- System.out.println("ERROR");
- return;
- }
- while (true) {
- try {
- System.out.println("Server Side......");
- Socket s = serverSocket.accept();
- InputStream input = s.getInputStream();
- OutputStream output = s.getOutputStream();
- BufferedInputStream bis = new BufferedInputStream(input);
- BufferedOutputStream bos = new BufferedOutputStream(output);
- byte[] buffer = new byte[20];
- bis.read(buffer);
- System.out.println(new String(buffer));
- bos.write("This is Server".getBytes());
- bos.flush();
- s.close();
- } catch (Exception e) {
- System.out.println(e);
- }
- }
- }
- public void init() {
- try {
- //取得SSLContext
- SSLContext ctx = SSLContext.getInstance(SERVER_AGREEMENT);
- //取得SunX509私钥管理器
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(SERVER_KEY_MANAGER);
- //取得JKS密库实例
- KeyStore ks = KeyStore.getInstance(SERVER_KEY_KEYSTORE);
- //加载服务端私钥
- ks.load(new FileInputStream(SERVER_KEYSTORE_PATH), SERVER_KEY_PASSWORD.toCharArray());
- //初始化
- kmf.init(ks, SERVER_KEY_PASSWORD.toCharArray());
- //初始化SSLContext
- ctx.init(kmf.getKeyManagers(),null, null);
- //通过SSLContext取得ServerSocketFactory,创建ServerSocket
- serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(SERVER_PORT);
- } catch (Exception e) {
- System.out.println(e);
- }
- }
- }
客户端:
- public class MySSLSocket extends Activity {
- private static final int SERVER_PORT = 50030;//端口号
- private static final String SERVER_IP = "218.206.176.146";//连接IP
- private static final String CLIENT_KET_PASSWORD = "123456";//私钥密码
- private static final String CLIENT_TRUST_PASSWORD = "123456";//信任证书密码
- private static final String CLIENT_AGREEMENT = "TLS";//使用协议
- private static final String CLIENT_KEY_MANAGER = "X509";//密钥管理器
- private static final String CLIENT_TRUST_MANAGER = "X509";//
- private static final String CLIENT_KEY_KEYSTORE = "BKS";//密库,这里用的是BouncyCastle密库
- private static final String CLIENT_TRUST_KEYSTORE = "BKS";//
- private static final String ENCONDING = "utf-8";//字符集
- private SSLSocket Client_sslSocket;
- private Log tag;
- private TextView tv;
- private Button btn;
- private Button btn2;
- private Button btn3;
- private EditText et;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- tv = (TextView) findViewById(R.id.TextView01);
- et = (EditText) findViewById(R.id.EditText01);
- btn = (Button) findViewById(R.id.Button01);
- btn2 = (Button) findViewById(R.id.Button02);
- btn3 = (Button) findViewById(R.id.Button03);
- btn.setOnClickListener(new Button.OnClickListener(){
- @Override
- public void onClick(View arg0) {
- if(null != Client_sslSocket){
- getOut(Client_sslSocket, et.getText().toString());
- getIn(Client_sslSocket);
- et.setText("");
- }
- }
- });
- btn2.setOnClickListener(new Button.OnClickListener(){
- @Override
- public void onClick(View arg0) {
- try {
- Client_sslSocket.close();
- Client_sslSocket = null;
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- });
- btn3.setOnClickListener(new View.OnClickListener(){
- @Override
- public void onClick(View arg0) {
- init();
- getIn(Client_sslSocket);
- }
- });
- }
- public void init() {
- try {
- //取得SSL的SSLContext实例
- SSLContext sslContext = SSLContext.getInstance(CLIENT_AGREEMENT);
- //取得KeyManagerFactory和TrustManagerFactory的X509密钥管理器实例
- KeyManagerFactory keyManager = KeyManagerFactory.getInstance(CLIENT_KEY_MANAGER);
- TrustManagerFactory trustManager = TrustManagerFactory.getInstance(CLIENT_TRUST_MANAGER);
- //取得BKS密库实例
- KeyStore kks= KeyStore.getInstance(CLIENT_KEY_KEYSTORE);
- KeyStore tks = KeyStore.getInstance(CLIENT_TRUST_KEYSTORE);
- //加客户端载证书和私钥,通过读取资源文件的方式读取密钥和信任证书
- kks.load(getBaseContext()
- .getResources()
- .openRawResource(R.drawable.kclient),CLIENT_KET_PASSWORD.toCharArray());
- tks.load(getBaseContext()
- .getResources()
- .openRawResource(R.drawable.lt_client),CLIENT_TRUST_PASSWORD.toCharArray());
- //初始化密钥管理器
- keyManager.init(kks,CLIENT_KET_PASSWORD.toCharArray());
- trustManager.init(tks);
- //初始化SSLContext
- sslContext.init(keyManager.getKeyManagers(),trustManager.getTrustManagers(),null);
- //生成SSLSocket
- Client_sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(SERVER_IP,SERVER_PORT);
- } catch (Exception e) {
- tag.e("MySSLSocket",e.getMessage());
- }
- }
- public void getOut(SSLSocket socket,String message){
- PrintWriter out;
- try {
- out = new PrintWriter(
- new BufferedWriter(
- new OutputStreamWriter(
- socket.getOutputStream()
- )
- ),true);
- out.println(message);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public void getIn(SSLSocket socket){
- BufferedReader in = null;
- String str = null;
- try {
- in = new BufferedReader(
- new InputStreamReader(
- socket.getInputStream()));
- str = new String(in.readLine().getBytes(),ENCONDING);
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- new AlertDialog
- .Builder(MySSLSocket.this)
- .setTitle("服务器消息")
- .setNegativeButton("确定", null)
- .setIcon(android.R.drawable.ic_menu_agenda)
- .setMessage(str)
- .show();
- }
- }
在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端之间Socket交互的更多相关文章
- Spring Boot+Socket实现与html页面的长连接,客户端给服务器端发消息,服务器给客户端轮询发送消息,附案例源码
功能介绍 客户端给所有在线用户发送消息 客户端给指定在线用户发送消息 服务器给客户端发送消息(轮询方式) 项目搭建 项目结构图 pom.xml <?xml version="1.0&q ...
- 加密、签名和SSL握手机制细节
openssl系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 1.1 背景知识 对称加密 :加密解密使用同一密钥,加解密速度快.随 ...
- JavaFX打包到Android上
让JavaFX执行到移动平台一直是社区努力完毕的事. 当然,眼下已经能够让JavaFX执行到Android和IOS平台了,以下我们来看看怎样打包自己的JavaFX项目到Android平台. 首先下 ...
- curl+个人证书(又叫客户端证书)访问https站点
摘自http://blog.csdn.net/chary8088/article/details/22990741 curl+个人证书(又叫客户端证书)访问https站点 目前,大公司的OA管理系统( ...
- node.js中通过dgram数据报模块创建UDP服务器和客户端
node.js中 dgram 模块提供了udp数据包的socket实现,可以方便的创建udp服务器和客户端. 一.创建UDP服务器和客户端 服务端: const dgram = require('dg ...
- SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码)
SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码) 摘自: https://blog.csdn.net/sjin_1314/article/det ...
- SSL 握手过程
SSL协议的握手过程 SSL 协议既用到了公钥加密技术又用到了对称加密技术,对称加密技术虽然比公钥加密技术的速度快,可是公钥加密技术提供了更好的身份认证技术.SSL 的握手协议非常有效的让客户和服务器 ...
- SSL握手过程
原文地址: http://my.oschina.net/u/1188877/blog/164982 一.SSL握手有三个目的:1. 客户端与服务器需要就一组用于保护数据的算法达成一致:2. 它们需要确 ...
- SSL握手流程
一.SSL是什么? 安全套接字(SSL)协议是Web浏览器和Web服务器之间安全交换信息的协议. SSL介于应用层和TCP层之间,应用层数据不再直接传递给传输层,而是传递给SSL层,SSL层对从应用层 ...
随机推荐
- 简单Spring和mybatis整合配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- 初识golang
golang是一门编译型的语言. 问题1:int和*int有啥区别?和c语言中有区别么? var a int = 32 var b *int = &a fmt.Println("ty ...
- eclipse安卓引入库项目的正确方法
之前清单文件里theme主题老是改不成库项目里定义好的主题@style/Theme.AppCompat.Light,只能用默认主题@style/AppTheme <application and ...
- springmvc上传图片,发送邮件
package hcxAction; import hcxMode.Advertises; import hcxMode.Areas; import hcxMode.Saveresume; impor ...
- PHP之输出控制 ob_start(),ob_get_contents(),ob_end_clean()
1.常用函数 ob_start();#打开输出缓冲区 ob_get_contents();#获取缓冲区内容 ob_get_length();#获取缓冲区内容长度 ob_clean();#清除之前的所有 ...
- hibernate ——helloWorld程序(XML配置)
1.项目结构 2.hibernate实现了Java类 和 数据库表的映射(Map) 先看一下Student的Java类和对应的数据库表 package com.pt.hibernate; public ...
- cocos2d-x中使用tinyxml遇到的问题及解决
1.问题: cocos2d-x集成tinyxml后在vs下运行正常,但是在Android下在读取xml文件时发生异常,读取时使用的是LoadFile函数 2. 解决方案: 先把xml文件内容读取到内存 ...
- ibatis 自动生成map,bean,dao
1.下载 AbatorForEclipse1.1.0 地址:http://download.csdn.net/detail/fym548/9426877 点击Archive按钮选择下载的,然后重启My ...
- OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)
OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰) 前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平.但不断有人反 ...
- property函数
__metaclass__=type class Rectangle: def __init__(self): self.width=0 sel ...