在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端之间Socket交互

Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库

服务端:
Java代码 收藏代码
  1. publicclassSSLServer{
  2. privatestaticfinalintSERVER_PORT=50030;
  3. privatestaticfinalStringSERVER_KEY_PASSWORD="123456";
  4. privatestaticfinalStringSERVER_AGREEMENT="TLS";//使用协议
  5. privatestaticfinalStringSERVER_KEY_MANAGER="SunX509";//密钥管理器
  6. privatestaticfinalStringSERVER_KEY_KEYSTORE="JKS";//密库,这里用的是Java自带密库
  7. privatestaticfinalStringSERVER_KEYSTORE_PATH="src/data/kserver.keystore";//密库路径
  8. privateSSLServerSocketserverSocket;
  9. publicstaticvoidmain(String[]args){
  10. SSLServerserver=newSSLServer();
  11. server.init();
  12. server.start();
  13. }
  14. //由于该程序不是演示Socket监听,所以简单采用单线程形式,并且仅仅接受客户端的消息,并且返回客户端指定消息
  15. publicvoidstart(){
  16. if(serverSocket==null){
  17. System.out.println("ERROR");
  18. return;
  19. }
  20. while(true){
  21. try{
  22. System.out.println("ServerSide......");
  23. Sockets=serverSocket.accept();
  24. InputStreaminput=s.getInputStream();
  25. OutputStreamoutput=s.getOutputStream();
  26. BufferedInputStreambis=newBufferedInputStream(input);
  27. BufferedOutputStreambos=newBufferedOutputStream(output);
  28. byte[]buffer=newbyte[20];
  29. bis.read(buffer);
  30. System.out.println(newString(buffer));
  31. bos.write("ThisisServer".getBytes());
  32. bos.flush();
  33. s.close();
  34. }catch(Exceptione){
  35. System.out.println(e);
  36. }
  37. }
  38. }
  39. publicvoidinit(){
  40. try{
  41. //取得SSLContext
  42. SSLContextctx=SSLContext.getInstance(SERVER_AGREEMENT);
  43. //取得SunX509私钥管理器
  44. KeyManagerFactorykmf=KeyManagerFactory.getInstance(SERVER_KEY_MANAGER);
  45. //取得JKS密库实例
  46. KeyStoreks=KeyStore.getInstance(SERVER_KEY_KEYSTORE);
  47. //加载服务端私钥
  48. ks.load(newFileInputStream(SERVER_KEYSTORE_PATH),SERVER_KEY_PASSWORD.toCharArray());
  49. //初始化
  50. kmf.init(ks,SERVER_KEY_PASSWORD.toCharArray());
  51. //初始化SSLContext
  52. ctx.init(kmf.getKeyManagers(),null,null);
  53. //通过SSLContext取得ServerSocketFactory,创建ServerSocket
  54. serverSocket=(SSLServerSocket)ctx.getServerSocketFactory().createServerSocket(SERVER_PORT);
  55. }catch(Exceptione){
  56. System.out.println(e);
  57. }
  58. }
  59. }

客户端:
Java代码 收藏代码
  1. publicclassMySSLSocketextendsActivity{
  2. privatestaticfinalintSERVER_PORT=50030;//端口号
  3. privatestaticfinalStringSERVER_IP="www.178zhe.com";//连接IP
  4. privatestaticfinalStringCLIENT_KET_PASSWORD="123456";//私钥密码
  5. privatestaticfinalStringCLIENT_TRUST_PASSWORD="123456";//信任证书密码
  6. privatestaticfinalStringCLIENT_AGREEMENT="TLS";//使用协议
  7. privatestaticfinalStringCLIENT_KEY_MANAGER="X509";//密钥管理器
  8. privatestaticfinalStringCLIENT_TRUST_MANAGER="X509";//
  9. privatestaticfinalStringCLIENT_KEY_KEYSTORE="BKS";//密库,这里用的是BouncyCastle密库
  10. privatestaticfinalStringCLIENT_TRUST_KEYSTORE="BKS";//
  11. privatestaticfinalStringENCONDING="utf-8";//字符集
  12. privateSSLSocketClient_sslSocket;
  13. privateLogtag;
  14. privateTextViewtv;
  15. privateButtonbtn;
  16. privateButtonbtn2;
  17. privateButtonbtn3;
  18. privateEditTextet;
  19. /**Calledwhentheactivityisfirstcreated.*/
  20. @Override
  21. publicvoidonCreate(BundlesavedInstanceState){
  22. super.onCreate(savedInstanceState);
  23. setContentView(R.layout.main);
  24. tv=(TextView)findViewById(R.id.TextView01);
  25. et=(EditText)findViewById(R.id.EditText01);
  26. btn=(Button)findViewById(R.id.Button01);
  27. btn2=(Button)findViewById(R.id.Button02);
  28. btn3=(Button)findViewById(R.id.Button03);
  29. btn.setOnClickListener(newButton.OnClickListener(){
  30. @Override
  31. publicvoidonClick(Viewarg0){
  32. if(null!=Client_sslSocket){
  33. getOut(Client_sslSocket,et.getText().toString());
  34. getIn(Client_sslSocket);
  35. et.setText("");
  36. }
  37. }
  38. });
  39. btn2.setOnClickListener(newButton.OnClickListener(){
  40. @Override
  41. publicvoidonClick(Viewarg0){
  42. try{
  43. Client_sslSocket.close();
  44. Client_sslSocket=null;
  45. }catch(IOExceptione){
  46. e.printStackTrace();
  47. }
  48. }
  49. });
  50. btn3.setOnClickListener(newView.OnClickListener(){
  51. @Override
  52. publicvoidonClick(Viewarg0){
  53. init();
  54. getIn(Client_sslSocket);
  55. }
  56. });
  57. }
  58. publicvoidinit(){
  59. try{
  60. //取得SSL的SSLContext实例
  61. SSLContextsslContext=SSLContext.getInstance(CLIENT_AGREEMENT);
  62. //取得KeyManagerFactory和TrustManagerFactory的X509密钥管理器实例
  63. KeyManagerFactorykeyManager=KeyManagerFactory.getInstance(CLIENT_KEY_MANAGER);
  64. TrustManagerFactorytrustManager=TrustManagerFactory.getInstance(CLIENT_TRUST_MANAGER);
  65. //取得BKS密库实例
  66. KeyStorekks=KeyStore.getInstance(CLIENT_KEY_KEYSTORE);
  67. KeyStoretks=KeyStore.getInstance(CLIENT_TRUST_KEYSTORE);
  68. //加客户端载证书和私钥,通过读取资源文件的方式读取密钥和信任证书
  69. kks.load(getBaseContext()
  70. .getResources()
  71. .openRawResource(R.drawable.kclient),CLIENT_KET_PASSWORD.toCharArray());
  72. tks.load(getBaseContext()
  73. .getResources()
  74. .openRawResource(R.drawable.lt_client),CLIENT_TRUST_PASSWORD.toCharArray());
  75. //初始化密钥管理器
  76. keyManager.init(kks,CLIENT_KET_PASSWORD.toCharArray());
  77. trustManager.init(tks);
  78. //初始化SSLContext
  79. sslContext.init(keyManager.getKeyManagers(),trustManager.getTrustManagers(),null);
  80. //生成SSLSocket
  81. Client_sslSocket=(SSLSocket)sslContext.getSocketFactory().createSocket(SERVER_IP,SERVER_PORT);
  82. }catch(Exceptione){
  83. tag.e("MySSLSocket",e.getMessage());
  84. }
  85. }
  86. publicvoidgetOut(SSLSocketsocket,Stringmessage){
  87. PrintWriterout;
  88. try{
  89. out=newPrintWriter(
  90. newBufferedWriter(
  91. newOutputStreamWriter(
  92. socket.getOutputStream()
  93. )
  94. ),true);
  95. out.println(message);
  96. }catch(IOExceptione){
  97. e.printStackTrace();
  98. }
  99. }
  100. publicvoidgetIn(SSLSocketsocket){
  101. BufferedReaderin=null;
  102. Stringstr=null;
  103. try{
  104. in=newBufferedReader(
  105. newInputStreamReader(
  106. socket.getInputStream()));
  107. str=newString(in.readLine().getBytes(),ENCONDING);
  108. }catch(UnsupportedEncodingExceptione){
  109. e.printStackTrace();
  110. }catch(IOExceptione){
  111. e.printStackTrace();
  112. }
  113. newAlertDialog
  114. .Builder(MySSLSocket.this)
  115. .setTitle("服务器消息")
  116. .setNegativeButton("确定",null)
  117. .setIcon(android.R.drawable.ic_menu_agenda)
  118. .setMessage(str)
  119. .show();
  120. }
  121. }

你可能感兴趣的:(android)