Android(安卓)SSL 过程记录(证书的生成+例子代码)
16lz
2022-06-09
在用Android平台上使用SSL,第一步就是生成证书。
1、证书的生成
1.1生成服务器端的证书
keytool -genkey -alias test -keystore test.jks1.2 将keystore中的cert导出来,用来生成客户端的验证证书
keytool -exportcert -alias test -file test.cert -keystore test.jks1.3 生成Android平台的证书
因为Android 要求要BC证书,而Java的keytool本身不提供BKS格式,因此要自己手动配置。个人在配置的过程到了文件正在使用中,保存失败的情况,我的做法是将文件备份一下,用unlocker删除后将修改好备份放到原位置就好了。
1.3.1 下载bcprov-ext-jdk15on-146.jar
可以选择到官网,也可以到我上传好的文件去下载,注意,用最新的149版本的会有证书版本号不对的异常,改用146的则没有这个问题
1.3.2 配置bcprov
在jdk_home\jre\lib\security\目录中找到java.security 在内容增加一行(数字可以自己定义)
security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider1.3.3 生成android平台的证书
keytool -importcert -keystore test.bks -file test.cert -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider2、编写服务器代码( 代码资源在这里)
主要代码(代码不是我原写的,作者已经在注释中标注了,工程文件在这里)
import java.io.BufferedInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketAddress;import java.security.KeyManagementException;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.UnrecoverableKeyException;import java.security.cert.CertificateException;import javax.net.ServerSocketFactory;import javax.net.ssl.KeyManager;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;/** * @author draem0507@gmail.com * @TODO java线程开发之四 SSL加密 * 开发步骤 * 1.生成服务端密钥 * 2.导出服务端证书 * 3.生成客户端密钥 * 4.程序开发测试 * 关于证书的生成请参考readme.txt * 参考资料:http://chrui.iteye.com/blog/1018778 * @version 1.0 * @date 2013-5-7 23:22:45 * @update 2013-5-8 10:22:45 * @blgos http://www.cnblogs.com/draem0507 */public class Server { private ServerSocket serverSocket; private final static char[] password="1qaz2wsx".toCharArray(); private SSLContext context; private InputStream inputStream; public Server() { inputStream=this.getClass().getResourceAsStream("/test.jks"); initContext(); try { //直接运行会报 javax.net.ssl.SSLException: //ServerSocketFactory factory= SSLServerSocketFactory.getDefault(); ServerSocketFactory factory= context.getServerSocketFactory();// serverSocket = new ServerSocket(10000); serverSocket=factory.createServerSocket(10000); System.out.println("======启动安全SocektServer成功========="); while (true) { Socket socket = serverSocket.accept(); new ReceiveSocket(socket).start(); } } catch (IOException e) { e.printStackTrace(); } } //ssl 上下文对象的初始化 private void initContext() { try { KeyStore store=KeyStore.getInstance("JKS"); store.load(inputStream, password); KeyManagerFactory factory=KeyManagerFactory.getInstance("SunX509"); factory.init(store,password); KeyManager []keyManagers=factory.getKeyManagers(); context=SSLContext.getInstance("SSL"); context.init(keyManagers, null , null); } catch (KeyStoreException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (UnrecoverableKeyException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } } public static void main(String[] args) { new Server(); } private class ReceiveSocket extends Thread { private Socket socket; public ReceiveSocket(Socket socket) { this.socket = socket; } private ObjectInputStream reader; private ObjectOutputStream writer; @Override public void run() { try { reader=new ObjectInputStream(new BufferedInputStream(socket.getInputStream())); //writer=new ObjectOutputStream(socket.getOutputStream()); // 开启无限循环 监控消息 //java.io.EOFException Object obj= reader.readUTF(); SocketAddress address = socket.getRemoteSocketAddress(); System.out.println(address.toString() + ">\t" + obj);// Object obj= reader.readObject();// if(obj!=null)// {// User user =(User)obj;// System.out.println("id=="+user.getPassword()+"\tname=="+user.getName());// } // while (true) {} } catch (IOException e) { e.printStackTrace(); } finally { if (null != reader) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != writer) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }}3、Android端代码
主要是发送数据的代码
protected Void doInBackground(Void... params) {Log.i(TAG, "doInBackground");try {SSLContext context;KeyStore ts = KeyStore.getInstance("BKS");ts.load(getResources().openRawResource(R.raw.test),"1qaz2wsx".toCharArray());TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");tmf.init(ts);TrustManager[] tm = tmf.getTrustManagers();context = SSLContext.getInstance("SSL");context.init(null, tm, null);SocketFactory factory = context.getSocketFactory();SSLSocket socket = (SSLSocket) factory.createSocket("192.168.70.249", 10000);ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());out.writeUTF(UUID.randomUUID().toString());out.flush();System.out.println("========客户端发送成功=========");;socket.close();} catch (Exception ex) {ex.printStackTrace();}return null;}
《好了,全文完》
-----感谢http://stackoverflow.com/ -----
更多相关文章
- android Button源码分析
- Cocos2d-x3.3RC0加载Android的WebView
- Android(安卓)SDK 源代码关联Eclipse
- Android中界面实现全屏显示的两种方式
- 史上最详细的Android(安卓)Studio系列教程三--快捷键
- 如何在unity中生成android工程
- Android(安卓)MVP 一行代码轻松解决框架替换
- build.prop生成及参数解析
- Android如何代码混淆