单项认证--服务器配置
生成服务器证书
命令:C:\Users\bwkt>keytool -genkey -alias server -keyalg RSA -keystore server.jks -validity 3650
-genkey:在用户主目录中创建一个默认文件".keystore"
-alias:别名,独一无二,通常不区分大小写
-keyalg: 指定密钥的算法 (如 RSA DSA(如果不指定默认采用DSA))
-keystore:指定密钥库的名称(产生的各类信息将不在.keystore文件中),可指定路径,例如:D:\keys\server.jks。
-validity:证书的有效期,单位:天。
A、输入keystore密码:此处需要输入大于6个字符的字符串。
B、“您的名字与姓氏是什么?”这是必填项。
C、你的组织单位名称是什么?”、“您的组织名称是什么?”、“您所在城市或区域名称是什么?”、“您所在的省/市/自治区名称是什么?”、“该单位的两字母国家代码是什么?”可以按照需要填写也可以不填写直接回车,在系统询问“正确吗?”时,对照输入信息,如果符合要求则使用键盘输入字母“y”,否则输入“n”重新填写上面的信息。
D、输入<bwkt>的密钥口令,这项较为重要,会在tomcat配置文件中使用,建议输入与keystore的密码一致,设置其它密码也可以,完成上述输入后,直接回车则在你在第二步中定义的位置找到生成的文件。
接下来利用server.jks来签发证书:
C:\Users\bwkt>keytool -export -alias server -file server.cer -keystore server.jks
配置Tomcat
找到tomcat/conf/sever.xml文件,并以文本形式打开。
找到端口为8443的标签,修改为:
<Connector SSLEnabled="true" acceptCount="100" clientAuth="true" disableUploadTimeout="true" enableLookups="true" keystoreFile="C:\Users\bwkt\server.jks" keystorePass="123456" maxSpareThreads="75" maxThreads="200" minSpareThreads="5" port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" sslProtocol="TLS" />
注:
keystoreFile:jks文件存放路径
keystorePass:生成证书时候的密码
测试
启动Tomcat服务器,在浏览器中输入 https://localhost:8443/ ,浏览器提示下图即为成功。
注:上面生成的server.cer是为Android客户端准备的。
单项认证--Android端
准备证书
在Android客户端启动的时候在Application中设置证书信息
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); try { // 证书放在assets文件夹中 OkHttpClientManager.getInstance().setCertificates(new InputStream[]{getAssets().open("server.cer")}); } catch (IOException e) { e.printStackTrace(); } OkHttpClientManager.getInstance().getOkHttpClient().setConnectTimeout(100000, TimeUnit.MILLISECONDS); } }
也可以通过命令获取到字符串:
C:\Users\bwkt>keytool -printcert -rfc -file server.cer
代码:
public class MyApplication extends Application { private static final String SERVER_CER = "-----BEGIN CERTIFICATE-----\n" + "MIIDSTCCAjGgAwIBAgIEd05HCTANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJjbjELMAkGA1UE\n" + "CBMCYmoxCzAJBgNVBAcTAmJqMQwwCgYDVQQKEwNzdW4xDTALBgNVBAsTBGJ3a3QxDzANBgNVBAMT\n" + "BnNlcnZlcjAeFw0xNTExMjAwMjAzMTRaFw0yNTExMTcwMjAzMTRaMFUxCzAJBgNVBAYTAmNuMQsw\n" + "CQYDVQQIEwJiajELMAkGA1UEBxMCYmoxDDAKBgNVBAoTA3N1bjENMAsGA1UECxMEYndrdDEPMA0G\n" + "A1UEAxMGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi98I4lBsevRZIPpX\n" + "4y0ocJrGHTNp4CBeNP+EXDs0ofqrdphd4U+rAs1pcYaC0yrXG8MdbS2E1ar4g3YOpuKNMtoac+gL\n" + "C+9+Ri+0Ge6o5Rwcly2JUUEJDyMVMxZTLJdGoaG2lkFRLbkHJDNil2hpnxMkU9f8BzTblTUOJvwX\n" + "MK0hgTDAwOyBcQRDTyKYT41Izn2ofk4UoGQdc2a7BmCZ9aRGkL2ZBtiuqDbebKV7+xZuyGIahCj0\n" + "K3odF61fQAbgDmaHpDiIvkWrRFuhTX6VuIfvrg1ek/fzSYJ2s6w40jDfGpGeaGbMjxcJ4DokwpRI\n" + "R//+7rbuPwH/BZ0KqxbifwIDAQABoyEwHzAdBgNVHQ4EFgQUorCf7tMptaAH6F53FbGO981Zhjow\n" + "DQYJKoZIhvcNAQELBQADggEBAAz+qTR3b7ezVdz3eL+n1qqrc+5GCp7aFhFTrT7GNsKP1A6MmYG9\n" + "j8H2IB58+AEnDGSrOKPFqHUlQSJzW05WDpCJorw8VXC4Mbsb8bP5jXmiJEakyic8dLoiZn3f4uNA\n" + "wWI4g8t/ZGAobG/X/d5Sd3Cyyi60BJoLcFIshjd3Z1YVl5V1c2Q8+k1qzfDno68Msu2IJ5LVbD44\n" + "Wmt03rlDP2bfeAvpX0PMyPS4RbILtvixLOUB5KM9LPOO7kliS6ZajVR/qDKo3H4fX2OCCYke4hsW\n" + "DR+iUT2S8FQEpBLQOyX6ULdELg0eMLhfmcUk2vvOaItF9LzeMim3tPPzs2XyWmA=\n" + "-----END CERTIFICATE-----"; @Override public void onCreate() { super.onCreate(); try { // 证书放在assets文件夹中 // OkHttpClientManager.getInstance().setCertificates(new InputStream[]{getAssets().open("server.cer")}); // 根据证书生成的字符串设置证书信息 OkHttpClientManager.getInstance().setCertificates(new InputStream[]{new Buffer().writeUtf8(SERVER_CER).inputStream()}); } catch (IOException e) { e.printStackTrace(); } OkHttpClientManager.getInstance().getOkHttpClient().setConnectTimeout(100000, TimeUnit.MILLISECONDS); } }
准备证书的核心代码如下:
1.设置OkHttpClient主机认证。
mOkHttpClient.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } });
2.设置证书信息
/** * 设置证书信息 * @param certificates * @param bksFile * @param password */ public void setCertificates(InputStream[] certificates, InputStream bksFile, String password) { try { TrustManager[] trustManagers = prepareTrustManager(certificates); KeyManager[] keyManagers = prepareKeyManager(bksFile, password); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagers, new TrustManager[] { new MyTrustManager(chooseTrustManager(trustManagers)) }, new SecureRandom()); mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } } /** * 准备所信任的服务器证书 * @param certificates * @return */ private TrustManager[] prepareTrustManager(InputStream... certificates) { if (certificates == null || certificates.length <= 0){ return null; } try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); int index = 0; for (InputStream certificate : certificates) { String certificateAlias = Integer.toString(index++); keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate)); try { if (certificate != null){ certificate.close(); } } catch (IOException e) { } } TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); return trustManagers; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 准备服务器信任的客户端的证书 * @param bksFile * @param password * @return */ private KeyManager[] prepareKeyManager(InputStream bksFile, String password) { try { if (bksFile == null || password == null) { return null; } // Android默认的是BKS格式的证书 KeyStore clientKeyStore = KeyStore.getInstance("BKS"); clientKeyStore.load(bksFile, password.toCharArray()); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(clientKeyStore, password.toCharArray()); return keyManagerFactory.getKeyManagers(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnrecoverableKeyException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; }
测试
String url = "https://192.168.0.163:8443/"; new OkHttpRequest.Builder().url(url).get( new MyResultCallback<String>() { @Override public void onError(Request request, Exception e) { Log.e(TAG, "onError" + e.getMessage()); textView.setText(e.getMessage()); }
注:只是获取的页面Html字符串。
双向认证--服务器配置
生成客户端证书
按照生成证书的方式,再生成一对这样的文件,我们命名为:client.jks,client.cer。
配置服务器
将端口为8443的标签,修改为:
<Connector SSLEnabled="true" acceptCount="100" clientAuth="true" disableUploadTimeout="true" enableLookups="true" keystoreFile="C:\Users\bwkt\server.jks" keystorePass="123456" truststoreFile="C:\Users\bwkt\client.jks" truststorePass="123456" maxSpareThreads="75" maxThreads="200" minSpareThreads="5" port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" sslProtocol="TLS" />
注:
truststoreFile:信任证书的文件路径
truststorePass:信任证书的秘密
测试
启动Tomcat服务器,在浏览器中输入 https://localhost:8443/ ,浏览器提示下图即为成功。
双向认证--Android端
生成Android所需的bks格式的证书
由于Java平台默认识别的是jks格式证书,Android默认识别的是bks格式证书,所有要将jks格式的证书转换成bks格式的证书。
步骤如下:
解压后,里面包含portecle.jar文件,双击portecle.jar即可打开GUI界面。
导入证书
点击
打开之前生成的jks文件。
输入密码:
成功打开。
转换证书
点击Tools-->Change keystore Type-->BKS。
输入密码,成功提示如下:
保存证书
Ctrl+s
准备证书
在Android客户端启动的时候在Application中设置证书信息
public class MyApplication extends Application { private static final String SERVER_CER = "-----BEGIN CERTIFICATE-----\n" + "MIIDSTCCAjGgAwIBAgIEd05HCTANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJjbjELMAkGA1UE\n" + "CBMCYmoxCzAJBgNVBAcTAmJqMQwwCgYDVQQKEwNzdW4xDTALBgNVBAsTBGJ3a3QxDzANBgNVBAMT\n" + "BnNlcnZlcjAeFw0xNTExMjAwMjAzMTRaFw0yNTExMTcwMjAzMTRaMFUxCzAJBgNVBAYTAmNuMQsw\n" + "CQYDVQQIEwJiajELMAkGA1UEBxMCYmoxDDAKBgNVBAoTA3N1bjENMAsGA1UECxMEYndrdDEPMA0G\n" + "A1UEAxMGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi98I4lBsevRZIPpX\n" + "4y0ocJrGHTNp4CBeNP+EXDs0ofqrdphd4U+rAs1pcYaC0yrXG8MdbS2E1ar4g3YOpuKNMtoac+gL\n" + "C+9+Ri+0Ge6o5Rwcly2JUUEJDyMVMxZTLJdGoaG2lkFRLbkHJDNil2hpnxMkU9f8BzTblTUOJvwX\n" + "MK0hgTDAwOyBcQRDTyKYT41Izn2ofk4UoGQdc2a7BmCZ9aRGkL2ZBtiuqDbebKV7+xZuyGIahCj0\n" + "K3odF61fQAbgDmaHpDiIvkWrRFuhTX6VuIfvrg1ek/fzSYJ2s6w40jDfGpGeaGbMjxcJ4DokwpRI\n" + "R//+7rbuPwH/BZ0KqxbifwIDAQABoyEwHzAdBgNVHQ4EFgQUorCf7tMptaAH6F53FbGO981Zhjow\n" + "DQYJKoZIhvcNAQELBQADggEBAAz+qTR3b7ezVdz3eL+n1qqrc+5GCp7aFhFTrT7GNsKP1A6MmYG9\n" + "j8H2IB58+AEnDGSrOKPFqHUlQSJzW05WDpCJorw8VXC4Mbsb8bP5jXmiJEakyic8dLoiZn3f4uNA\n" + "wWI4g8t/ZGAobG/X/d5Sd3Cyyi60BJoLcFIshjd3Z1YVl5V1c2Q8+k1qzfDno68Msu2IJ5LVbD44\n" + "Wmt03rlDP2bfeAvpX0PMyPS4RbILtvixLOUB5KM9LPOO7kliS6ZajVR/qDKo3H4fX2OCCYke4hsW\n" + "DR+iUT2S8FQEpBLQOyX6ULdELg0eMLhfmcUk2vvOaItF9LzeMim3tPPzs2XyWmA=\n" + "-----END CERTIFICATE-----"; @Override public void onCreate() { super.onCreate(); try { // 证书放在assets文件夹中 // OkHttpClientManager.getInstance().setCertificates(new InputStream[]{getAssets().open("server.cer")}); // 根据证书生成的字符串设置证书信息 // OkHttpClientManager.getInstance().setCertificates(new InputStream[]{new Buffer().writeUtf8(SERVER_CER).inputStream()}); // 双向认证,设置证书信息 OkHttpClientManager.getInstance().setCertificates(new InputStream[]{getAssets().open("server.cer")}, getAssets().open("client.bks"), "123456"); } catch (IOException e) { e.printStackTrace(); } OkHttpClientManager.getInstance().getOkHttpClient().setConnectTimeout(100000, TimeUnit.MILLISECONDS); } }
测试
String url = "https://192.168.0.163:8443/"; new OkHttpRequest.Builder().url(url).get( new MyResultCallback<String>() { @Override public void onError(Request request, Exception e) { Log.e(TAG, "onError" + e.getMessage()); textView.setText(e.getMessage()); } @Override public void onResponse(String response) { textView.setText(response); } });
注:只是获取的页面Html字符串。
相关推荐
通过搭建简单的服务器端与客户端,以及配置HTTPS环境,可以有效提升应用程序的安全性。对于实际应用来说,还可以进一步优化服务器端的处理逻辑,增强客户端的安全认证机制,从而提供更加可靠和安全的服务。
本文将详细介绍`IOS`和`Android`平台上如何实现`SSL`双向认证以及配置证书。 首先,理解`SSL`双向认证的概念。常规的`SSL`单向认证中,服务器会验证客户端的身份,但客户端并不验证服务器的身份。而在双向认证中,...
自签名证书是由服务器自身生成并签名的,而非由权威CA签发。这使得自签名证书无法被广泛信任,因为没有第三方证明其真实性。在Android设备上,系统默认不会信任这类证书,因此在尝试连接使用自签名证书的服务器时,...
Debug证书是用于调试阶段的,它默认由Android Studio自动生成,使得开发者能够在设备或模拟器上快速安装和测试应用。Release证书则是用于发布应用到Google Play或其他第三方应用市场,它需要开发者自己创建并妥善...
只需简单在配置文件中指定即可,证书完全兼容与Windows、Linux、Android、iOS等PC及手机系统(自签名不兼容)。项目是产品化的,不用修改代码就可以管理CA服务器整个生命周期,计划未来增加web操作页面,实现用户从...
对于使用Jetty服务器的项目来说,配置HTTPS支持是一项重要的任务。本文将详细介绍如何在Jetty中配置HTTPS,并生成受信的网站证书。 #### 二、Jetty HTTPS配置步骤 ##### 1. 生成证书 第一步是生成一个自签名证书...
5. **安全性**:考虑到网络通信的安全性,可能涉及到HTTPS协议,服务器端证书配置,以及请求的验证,如OAuth或Token机制。 6. **性能优化**:为了匹配Volley的高效特性,服务器端也需要进行性能优化,如缓存策略、...
在Swift编程领域,自动生成自签名HTTPS服务器是一个实用的技术,尤其对于iOS和Android开发者来说,它能方便快捷地部署和安装ipa与apk应用。本文将深入探讨这一主题,基于"ios-ipa-server"项目,解释如何创建这样的...
这需要在Servlet配置SSL证书,并在Android客户端设置信任所有证书或自定义证书。 9. **WebSocket实现长连接**:虽然HTTP请求能实现基本的通讯,但为了实现实时通讯,我们可能需要使用WebSocket,它提供全双工、持久...
此项目“android 使用HttpsURLConnection方式的SSL双向认证”着重讲解了如何在Android应用中通过HttpsURLConnection实现SSL的客户端和服务器端之间的双向身份验证,确保通信的隐私和完整性。 首先,我们需要理解SSL...
本文详细介绍了如何使用`AndroidHttpClient`访问`Tomcat`双向SSL验证服务器的过程,包括证书生成、Tomcat配置、客户端验证等多个方面。通过对这些步骤的详细解析,不仅解决了实际项目中的问题,也为读者提供了一个...
如果验证通过,客户端会生成一个随机密钥,并使用服务器的公钥加密这个密钥。 3. **密钥交换**:客户端将加密后的随机密钥发送给服务器。由于只有服务器持有对应的私钥,所以即使数据在传输过程中被截取,也无法...
1. **证书生成**:首先,我们需要为客户端和服务器分别生成数字证书。Portecle是一个常用的Java密钥工具,可用于生成RSA密钥对和证书。在`portecle-1.11.zip`中,我们可以找到这个工具。打开Portecle,创建一个新的...
Android需要配置信任的证书,PHP服务器则需配置SSL证书。 10. **错误处理与日志记录**:在Android客户端和PHP服务器端都要进行适当的错误处理,记录日志,以便调试和问题排查。 通过分析"源码的重要性.txt"和...
这涉及到SSL/TLS证书配置,Android端可能需要处理信任自签名证书的问题。 6. **Android权限管理**:Android 6.0及以上版本引入了运行时权限管理,访问网络可能需要请求`INTERNET`权限。开发者需要在代码中检查并...
- 服务器证书:首先,你需要为服务器生成一个自我签名的证书,这可以通过Java的keytool工具完成。创建一个Key Pair(公钥和私钥),然后将公钥打包成X.509证书。 - 客户端证书:类似地,也需要为客户端生成一个...
**3.2 生成服务器和客户端所需密钥和证书** 使用Keytool和OpenSSL生成CSR(Certificate Signing Request),然后使用CA(Certificate Authority)签发证书,或者自签发证书。 ### 4. 搭建服务器端 **4.1. 在...
这个系统通常涉及客户端(如Android设备)和服务器端(通常用JavaWeb技术实现)的交互。让我们深入探讨一下这个"Android客户端+JavaWeb服务器远程登录"的相关知识点。 1. **Android客户端开发**: - **Activity和...