在Android上实现SSL握手

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();
    }
}

你可能感兴趣的:(jdk,android,socket,配置管理)