当前位置: 代码迷 >> Android >> 在Android上兑现SSL握手
  详细解决方案

在Android上兑现SSL握手

热度:51   发布时间:2016-05-01 18:32:39.0
在Android上实现SSL握手
Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库

服务端:
Java代码 
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); 
        } 
    } 


客户端:
Java代码 
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(); 
    } 
  相关解决方案