在用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/ -----
版权声明:本文为acnt3w原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。