android 实现SSL握手协商

Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库  ssl通道建立前必须进行协商(形成安全的通道--隧道技术)。

服务端:

View Code
 1 public class SSLServer {
 2 
 3     private static final int SERVER_PORT = 50030;
 4     private static final String SERVER_KEY_PASSWORD = "123456";
 5     private static final String SERVER_AGREEMENT = "TLS";//使用协议
 6     private static final String SERVER_KEY_MANAGER = "SunX509";//密钥管理器
 7     private static final String SERVER_KEY_KEYSTORE = "JKS";//密库,这里用的是Java自带密库
 8     private static final String SERVER_KEYSTORE_PATH = "src/data/kserver.keystore";//密库路径
 9     private SSLServerSocket serverSocket;
10 
11     public static void main(String[] args) {
12         SSLServer server = new SSLServer();
13         server.init();
14         server.start();
15     }
16 
17     //由于该程序不是演示Socket监听,所以简单采用单线程形式,并且仅仅接受客户端的消息,并且返回客户端指定消息
18     public void start() {
19         if (serverSocket == null) {
20             System.out.println("ERROR");
21             return;
22         }
23         while (true) {
24             try {
25                 System.out.println("Server Side......");
26                 Socket s = serverSocket.accept();
27                 InputStream input = s.getInputStream();
28                 OutputStream output = s.getOutputStream();
29 
30                 BufferedInputStream bis = new BufferedInputStream(input);
31                 BufferedOutputStream bos = new BufferedOutputStream(output);
32 
33                 byte[] buffer = new byte[20];
34                 bis.read(buffer);
35                 System.out.println(new String(buffer));
36 
37                 bos.write("This is Server".getBytes());
38                 bos.flush();
39 
40                 s.close();
41             } catch (Exception e) {
42                 System.out.println(e);
43             }
44         }
45     }
46     
47     public void init() {
48         try {
49             //取得SSLContext
50             SSLContext ctx = SSLContext.getInstance(SERVER_AGREEMENT);
51             //取得SunX509私钥管理器
52             KeyManagerFactory kmf = KeyManagerFactory.getInstance(SERVER_KEY_MANAGER);
53             //取得JKS密库实例
54             KeyStore ks = KeyStore.getInstance(SERVER_KEY_KEYSTORE);
55             //加载服务端私钥
56             ks.load(new FileInputStream(SERVER_KEYSTORE_PATH), SERVER_KEY_PASSWORD.toCharArray());
57             //初始化
58             kmf.init(ks, SERVER_KEY_PASSWORD.toCharArray());
59             //初始化SSLContext
60             ctx.init(kmf.getKeyManagers(),null, null);
61             //通过SSLContext取得ServerSocketFactory,创建ServerSocket
62             serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(SERVER_PORT);
63         } catch (Exception e) {
64             System.out.println(e);
65         }
66     }
67 }

客户端:

View Code
  1 public class MySSLSocket extends Activity {
  2     private static final int SERVER_PORT = 50030;//端口号
  3     private static final String SERVER_IP = "218.206.176.146";//连接IP
  4     private static final String CLIENT_KET_PASSWORD = "123456";//私钥密码
  5     private static final String CLIENT_TRUST_PASSWORD = "123456";//信任证书密码
  6     private static final String CLIENT_AGREEMENT = "TLS";//使用协议
  7     private static final String CLIENT_KEY_MANAGER = "X509";//密钥管理器
  8     private static final String CLIENT_TRUST_MANAGER = "X509";//
  9     private static final String CLIENT_KEY_KEYSTORE = "BKS";//密库,这里用的是BouncyCastle密库
 10     private static final String CLIENT_TRUST_KEYSTORE = "BKS";//
 11     private static final String ENCONDING = "utf-8";//字符集
 12     private SSLSocket Client_sslSocket;
 13     private Log tag;
 14     private TextView tv;
 15     private Button btn;
 16     private Button btn2;
 17     private Button btn3;
 18     private EditText et;
 19     
 20     /** Called when the activity is first created. */
 21     @Override
 22     public void onCreate(Bundle savedInstanceState) {
 23         super.onCreate(savedInstanceState);
 24         setContentView(R.layout.main);
 25         tv = (TextView) findViewById(R.id.TextView01);
 26         et = (EditText) findViewById(R.id.EditText01);
 27         btn = (Button) findViewById(R.id.Button01);
 28         btn2 = (Button) findViewById(R.id.Button02);
 29         btn3 = (Button) findViewById(R.id.Button03);
 30         
 31         btn.setOnClickListener(new Button.OnClickListener(){
 32             @Override
 33             public void onClick(View arg0) {
 34                 if(null != Client_sslSocket){
 35                     getOut(Client_sslSocket, et.getText().toString());
 36                     getIn(Client_sslSocket);
 37                     et.setText("");
 38                 }
 39             }
 40         });
 41         btn2.setOnClickListener(new Button.OnClickListener(){
 42             @Override
 43             public void onClick(View arg0) {
 44                 try {
 45                     Client_sslSocket.close();
 46                     Client_sslSocket = null;
 47                 } catch (IOException e) {
 48                     e.printStackTrace();
 49                 }
 50             }
 51         });
 52         btn3.setOnClickListener(new View.OnClickListener(){
 53             @Override
 54             public void onClick(View arg0) {
 55                 init();
 56                 getIn(Client_sslSocket);
 57             }
 58         });
 59     }
 60     
 61     public void init() {
 62         try {
 63             //取得SSL的SSLContext实例
 64             SSLContext sslContext = SSLContext.getInstance(CLIENT_AGREEMENT);
 65             //取得KeyManagerFactory和TrustManagerFactory的X509密钥管理器实例
 66             KeyManagerFactory keyManager = KeyManagerFactory.getInstance(CLIENT_KEY_MANAGER);
 67             TrustManagerFactory trustManager = TrustManagerFactory.getInstance(CLIENT_TRUST_MANAGER);
 68             //取得BKS密库实例
 69             KeyStore kks= KeyStore.getInstance(CLIENT_KEY_KEYSTORE);
 70             KeyStore tks = KeyStore.getInstance(CLIENT_TRUST_KEYSTORE);
 71             //加客户端载证书和私钥,通过读取资源文件的方式读取密钥和信任证书
 72             kks.load(getBaseContext()
 73                     .getResources()
 74                     .openRawResource(R.drawable.kclient),CLIENT_KET_PASSWORD.toCharArray());
 75             tks.load(getBaseContext()
 76                     .getResources()
 77                     .openRawResource(R.drawable.lt_client),CLIENT_TRUST_PASSWORD.toCharArray());
 78             //初始化密钥管理器
 79             keyManager.init(kks,CLIENT_KET_PASSWORD.toCharArray());
 80             trustManager.init(tks);
 81             //初始化SSLContext
 82             sslContext.init(keyManager.getKeyManagers(),trustManager.getTrustManagers(),null);
 83             //生成SSLSocket
 84             Client_sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(SERVER_IP,SERVER_PORT);
 85         } catch (Exception e) {
 86             tag.e("MySSLSocket",e.getMessage());
 87         }
 88     }
 89         
 90     public void getOut(SSLSocket socket,String message){
 91         PrintWriter out;
 92         try {
 93             out = new PrintWriter(
 94                     new BufferedWriter(
 95                             new OutputStreamWriter(
 96                                     socket.getOutputStream()
 97                                     )
 98                             ),true);
 99             out.println(message);
100         } catch (IOException e) {
101             e.printStackTrace();
102         }
103     }
104     
105     public void getIn(SSLSocket socket){
106         BufferedReader in = null;
107         String str = null;
108         try {
109             in = new BufferedReader(
110                     new InputStreamReader(
111                             socket.getInputStream()));
112             str = new String(in.readLine().getBytes(),ENCONDING);
113         } catch (UnsupportedEncodingException e) {
114             e.printStackTrace();
115         } catch (IOException e) {
116             e.printStackTrace();
117         }
118         new AlertDialog
119         .Builder(MySSLSocket.this)
120         .setTitle("服务器消息")
121         .setNegativeButton("确定", null)
122         .setIcon(android.R.drawable.ic_menu_agenda)
123         .setMessage(str)
124         .show();
125     }
126 }
原文地址:https://www.cnblogs.com/sunfb/p/2935525.html