您的位置:首页 > 理论基础 > 计算机网络

在android上实现ssl双向通信(https形式)

2013-11-06 18:34 127 查看
首先上一篇已经说了,我也就有了不罗嗦了,走起:
public static String Httpsdemo(Context context) throws NoSuchAlgorithmException, KeyStoreException,
CertificateException, IOException, UnrecoverableKeyException, KeyManagementException, InterruptedException, ExecutionException
{
SSLContext sslContext = SSLContext.getInstance("TLS");

KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");

KeyStore kks = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore tks = KeyStore.getInstance(KeyStore.getDefaultType());

InputStream keyStoreStream = HttpClientTest.class.getResourceAsStream("/assets/client.keystore");
InputStream tkeyStoreStream = HttpClientTest.class.getResourceAsStream("/assets/newtrust.bks");

char[] keyStorePassword = "123456".toCharArray();
char[] certificatePassword = "123456".toCharArray();

CertificateFactory cf = CertificateFactory.getInstance("X.509");

String cerUrl = Environment.getExternalStorageDirectory().getPath() + "/client.bks";
InputStream clientInput = new BufferedInputStream(HttpClientTest.class.getResourceAsStream("/assets/client.crt"));
Certificate clientcer;
try {
clientcer = cf.generateCertificate(clientInput);
} finally {
clientInput.close();
}

kks.load(keyStoreStream, keyStorePassword);
tks.load(tkeyStoreStream,keyStorePassword);
Key key = kks.getKey("client",keyStorePassword);//这里是你建立keystore时的别名
kks = KeyStore.getInstance("BKS");
kks.load(null,null);
kks.setKeyEntry("client",key,keyStorePassword,new Certificate[]{clientcer});
		kks.store();//这里你就可以用输出流把你生成的keystore给生成文件。kmf.init(kks, certificatePassword);tmf.init(tks);KeyManager[] keyManagers = kmf.getKeyManagers();TrustManager[] TrustManager = tmf.getTrustManagers();SecureRandom secureRandom = new SecureRandom();sslContext.init(keyManagers, TrustManager, secureRandom);//		从这里网上的部分就是组织建立ssl通道所需要的sslContext,里面有https需要的证书私钥等。
//		并且单向跟双向的区别可以在这个看到,单项的话是不需要keyManagers的,所以单向的话把这一项填上nullString result = "";HttpsURLConnection http = null;URL url;try{url = new URL("https://你要访问的地址/");//			url = new URL("https://www.google.com.hk/intl/zh-CN/policies/terms/regional.html");http = (HttpsURLConnection) url.openConnection();((HttpsURLConnection) http).setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);// 不进行主机名确认http.setSSLSocketFactory(sslContext.getSocketFactory());http.setConnectTimeout(200000);// 设置超时时间http.setReadTimeout(200000);http.setRequestMethod("POST");// 设置请求类型为posthttp.setDoInput(true);http.setDoOutput(true);http.setRequestProperty("connection", "keep-alive");http.setRequestProperty("Charsert", "UTF-8");http.setRequestProperty("Content-Type", "application/octet-stream");DataOutputStream out = new DataOutputStream(http.getOutputStream());String postdata = "你的数据";out.write(postdata.getBytes());out.flush();out.close();BufferedReader in = null;if (http.getResponseCode() == 200){in = new BufferedReader(new InputStreamReader(http.getInputStream()));}else{in = new BufferedReader(new InputStreamReader(http.getErrorStream()));}String line = "";while ((line = in.readLine()) != null) {result += line + "\n";}//			result = in.readLine();// 得到返回结果in.close();http.disconnect();System.out.println(result);}catch (Exception e){e.printStackTrace();}
}
在这里上面的代码都是没有问题的,现在就说一下问题吧,首先:这里面的两个BKS文件从哪来?答:trust.bks,我们把服务器证书和CA证书导入到里面就可以了,注意:用记事本打开,把两个证书合并成一个文件再导入,否则不知道会出现什么错误。。。xxx.bks,需要我们自己去生成,我的做法是这样的:首先用keytool工具生成一个BKS类型的keystore,导出证书请求,CA签过名之后,拿到证书文件,在程序里面加载keystore文件,提取出来私钥,然后重新生成一个全新的BKS类型的keystore把key和证书导入进去,然后导出到文件,至此就拿到了客户端的密钥库。这里面可能还会有证书类型不对的情况,这可能是由于你的服务器端的证书不是用BC生成的,这些你都可以跟CA的沟通,最后祝大家顺利。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 通信 ssl