Android与Windows Socket通信,TLS双向认证

Android设备作为客户端,与PC服务端进行双向认证、基于TLS 1.2协议socket通信。

  • 证书制作
  • CA签发
  • JKS转换BKS
  • 加密套件修改
  • 双向认证demo

证书制作

由于是双向认证,需要制作客户端和服务器证书,这里用到的是JAVA自带的keytool工具(请自行安装JDK环境)。
话不多说,上证书制作脚本:
1)生成服务器端公私钥对,存入密钥库,命令keytool -genkeypair:

keytool -genkeypair -alias serverkey -keyalg ec -validity 365 -keystore serverkey.keystore.jks  -storepass 1234567 -dname "cn=AA.COM, ou=AA, o=AA Cor, c=CN, l=SZ" -deststoretype pkcs12
参数 含义
-alias 设置别名,可自定义
-keyalg 设置密钥算法,DSA、RSA、ECDSA等
-valiity 有效期
-keystore 密钥库名称
-storepass 密钥库密码
-dname 指定证书发行方信息
-deststoretype 指定keystore类型,默认pkcs12

2)同理,生成客户端公私钥对:

keytool -genkeypair -alias clientkey -keyalg ec -validity 365 -keystore clientkey.keystore.jks  -storepass 7654321 -dname "cn=BB.COM, ou=BB, o=BB Cor, c=CN, l=SZ" -deststoretype pkcs12

这样就生成了自签名的服务器证书和客户端证书。

CA签发

虽然我们将服务器与客户端密钥库分别提交给对方加入到各自受信任密钥库,在通信的时候互相校验,可以做到双向认证通过,但通常情况下不会这样做,一来直接将证书丢给对方很不安全,密钥库被盗用即有身份被冒用风险;二来客户端和服务端的密钥库一旦签发给对方,其存储的证书内容被固定住,无法扩展。

所以我们引入第三方受信CA,客户端和服务端分别只要信任该CA,则该CA签发的证书都是可信任的。

由于市面上流通的知名CA都是收费签发,这里使用自签CA来模拟这个过程。

1)首先生成CA密钥库:

keytool -genkeypair -alias rootca -keyalg ec -validity 3650 -keystore ca.keystore.jks -storepass  22222222 -dname "cn=CA.COM, ou=CA, o=CA Cor, c=CN, l=SZ" -deststoretype pkcs12

2)导出CA证书,用于后续导入到密钥库:
···
keytool -exportcert -alias rootca -file ca.cer -keystore ca.keystore.jks -storepass 22222222 -deststoretype pkcs12
···
3)生成服务器端证书请求serverkey.csr,即是待签发的证书文件:

keytool -certreq -alias serverkey -keystore serverkey.keystore.jks -storepass 1234567 -file  serverkey.csr -deststoretype pkcs12

4)使用 CA密钥库ca.keystore.jks对serverkey.csr进行签发:

keytool -gencert -alias rootca -infile serverkey.csr -outfile serverkey.cer -validity 365  -keystore ca.keystore.jks -storepass 22222222 -deststoretype pkcs12

使用keytool -printcert命令可以看到签发者变成了CA(CA.COM):

5)导入CA证书到服务器密钥库:

keytool -import -trustcacerts -alias rootca -file ca.cer -keystore serverkey.keystore.jks  -storepass 1234567 -deststoretype pkcs12

导入时会提示是否信任,输入y,表示信任

6)导入签发证书到服务器密钥库:

keytool -import -trustcacerts -alias serverkey -file serverkey.cer -keystore  serverkey.keystore.jks -storepass 1234567 -deststoretype pkcs12

使用keytool -list -v命令查看密钥库可以看到有两个证书,一个是签发后的密钥,一个是CA,其中密钥签发者变成了CA(CA.COM):

7)同理生成客户端证书请求并使用CA签发:

keytool -certreq -alias clientkey -keystore clientkey.keystore.jks -storepass 7654321 -file  clientkey.csr -deststoretype pkcs12
keytool -gencert -alias rootca -infile clientkey.csr -outfile clientkey.cer -validity 365  -keystore ca.keystore.jks -storepass 22222222 -deststoretype pkcs12
keytool -import -trustcacerts -alias rootca -file ca.cer -keystore clientkey.keystore.jks  -storepass 7654321 -deststoretype pkcs12
keytool -import -trustcacerts -alias clientkey -file clientkey.cer -keystore  clientkey.keystore.jks -storepass 7654321 -deststoretype pkcs12

至此,双向认证的JKS证书已经制作完成。

密钥库转换

我们这里是Android客户端,不能直接使用JKS密钥,需要用BKS格式密钥文件。

这里借助portecle https://sourceforge.net/projects/portecle/files/latest/download 工具进行转换:
下载解压缩后,进入相应目录,执行

java -jar portecle.jar

即可打开软件主界面:

转换服务器/客户端密钥库:

转换CA密钥库:
首先将CA证书导入到一个新的JKS格式CA密钥库cacer.keystore.jks:

keytool -importcert -alias rootca -file ca.cer -keystore cacer.keystore.jks  -storepass 33333333 

然后类似服务器BKS密钥库转换方式进行转换得到ca.keystore.bks【注意!!此时CA密钥库密码变为新密码 33333333

这样我们拿到了三个BKS密钥库:

密钥库 用途
ca.keystore.bks 服务器和客户端各持一份,用于验签对方证书
serverkey.keystore.bks 服务器持有,双向认证时发给客户端
clientkey.keystore.bks 客户端持有,双向认证时发给服务器

加密套件修改

加密套件(Ciphe Suites)是指在ssl/tls通信中,服务器和客户端所使用的加密算法的组合。在ssl握手初期,客户端将自身支持的加密套件列表发送给服务器;在握手阶段,服务器根据自己的配置从中尽可能的选出一个套件,作为之后所要使用的加密方式。这些算法包括:认证算法、密钥交换算法、对称算法和摘要算法等。

随着技术的发展,某些加密套件由于算法安全级别不够,不需要出现在双向认证的候选加密套件列表中,只需在openssl源码SSL_CIPHER kCiphers[]列表进行移除即可,比如下面去掉Cipher 04、Cipher 05、Cipher 0A:

/* kCiphers is an array of all supported ciphers, sorted by id. */
static const SSL_CIPHER kCiphers[] = {/* The RSA ciphers *//* Cipher 02 */{SSL3_TXT_RSA_NULL_SHA,SSL3_CK_RSA_NULL_SHA,SSL_kRSA,SSL_aRSA,SSL_eNULL,SSL_SHA1,SSL_HANDSHAKE_MAC_DEFAULT,},
/*/* Cipher 04 *{SSL3_TXT_RSA_RC4_128_MD5,SSL3_CK_RSA_RC4_128_MD5,SSL_kRSA,SSL_aRSA,SSL_RC4,SSL_MD5,SSL_HANDSHAKE_MAC_DEFAULT,},/* Cipher 05 *{SSL3_TXT_RSA_RC4_128_SHA,SSL3_CK_RSA_RC4_128_SHA,SSL_kRSA,SSL_aRSA,SSL_RC4,SSL_SHA1,SSL_HANDSHAKE_MAC_DEFAULT,},/* Cipher 0A {SSL3_TXT_RSA_DES_192_CBC3_SHA,SSL3_CK_RSA_DES_192_CBC3_SHA,SSL_kRSA,SSL_aRSA,SSL_3DES,SSL_SHA1,SSL_HANDSHAKE_MAC_DEFAULT,},
*/...
};

Android应用层,若是使用SSLSocket,则只需使用setEnabledCipherSuites方法设置想要的加密套件:

        List<String> allowedCiphers = Arrays.asList(// TLS 1.2"TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",// maximum interoperability//"SSL_RSA_WITH_3DES_EDE_CBC_SHA", // FAQ 69"TLS_RSA_WITH_AES_128_CBC_SHA",// additionally"TLS_RSA_WITH_AES_256_CBC_SHA",//"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",//"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");String[] enabledCiphers=allowedCiphers.toArray(new String[allowedCiphers.size()]);Client_sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(SERVER_IP,SERVER_PORT);String[] supportSuite = Client_sslSocket.getSupportedCipherSuites();Client_sslSocket.setEnabledCipherSuites(enabledCiphers);

完整demo代码见 https://download.csdn.net/download/peterhu_112/10606499

【参考】 https://docs.oracle.com/javase/8/docs/technotes/tools/windows/keytool.html

Android与Windows Socket通信,TLS双向认证相关推荐

  1. CA、TLS双向认证

    1.名词解释 TLS:传输层安全协议 Transport Layer Security的缩写 CA 证书颁发机构(CA, Certificate Authority)即颁发数字证书的机构. CSR 是 ...

  2. SSL/TLS 双向认证(一) -- SSL/TLS工作原理

    本文部分参考: https://www.wosign.com/faq/faq2016-0309-03.htm https://www.wosign.com/faq/faq2016-0309-04.ht ...

  3. SSL/TLS 双向认证(一) -- SSL/TLS 工作原理

    本文部分参考: https://www.wosign.com/faq/faq2016-0309-03.htm https://www.wosign.com/faq/faq2016-0309-04.ht ...

  4. SSL/TLS 双向认证

    其他参考链接 链接: https://blog.csdn.net/xxss120/article/details/78758832. 链接: https://blog.csdn.net/gx_1983 ...

  5. TLS双向认证之生成双端证书信息

    目录 TLS双向认证需要的认证文件 制作根证书 第三方机构的根证书 自签根证书(基于openssl) 根证书签发证书 服务端证书 客户端证书 最终需要使用的文件 TLS双向认证需要的认证文件 服务端: ...

  6. 基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互

    基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互 一.前言 1.Java服务端程序代码的项目名为TcpSocketServerOfJava,包名为com.exam ...

  7. Linux Windows Socket通信 端口开启

    Centos查看端口占用情况命令,比如查看80端口占用情况使用如下命令: lsof -i tcp:80 列出所有端口 netstat -ntlp 1.开启端口(以80端口为例) 方法一:/sbin/i ...

  8. c++使用OpenSSL基于socket实现tcp双向认证ssl(使用TSL协议)代码实现

    相信各位对OpenSSL库已经不陌生了,目前笔者使用这个库实现了RSA.AES加解密和tcp的双向认证功能,下面来看tcp的双向认证. 1.什么是双向认证 简单说双向认证就是:客户端认证服务端是否合法 ...

  9. (转载)Android 让WebView完美支持https双向认证(SSL)

    (转载)https://blog.csdn.net/kpioneer123/article/details/51491739 这是@happyzhang0502   关于webview https的建 ...

  10. Android本地服务器NanoHttpd配置Https双向认证

    一. 了解数字证书 在HTTPS的传输过程中,有一个非常关键的角色--数字证书,那什么是数字证书?又有什么作用呢? 所谓数字证书,是一种用于电脑的身份识别机制.由数字证书颁发机构(CA)对使用私钥创建 ...

最新文章

  1. 【学术写作】写综述小窍门,教你轻松写综述
  2. rpm安装mysql报错NOKEY_rpm包安装报错: Header V3 RSASHA256 Signature, key ID fd431d51 NOKEY
  3. 在reader中勾选pdf复选框_绝对可勾选的在WORD 2003中加入复选框的方法
  4. 计算机复试专业课笔试,2017年杭州电子科技大学计算机考研复试经验分享,复试专业课笔试题真题回忆!...
  5. 支付宝客户端架构分析:自动化日志收集及分析
  6. 信息学奥赛一本通 1055:判断闰年 | OpenJudge NOI 1.4 17
  7. csv导入mysql php实现_PHP实现csv文件导入mysql数据库的方法
  8. Kali Linux 网络扫描秘籍 第八章 自动化 Kali 工具
  9. 【点阵液晶编程连载二】LCD 驱动的基本流程
  10. BootStrap里面好看的背景色
  11. 微服务分布式企业框架 Springmvc+mybatis+shiro+Dubbo+ZooKeeper
  12. SharePoint 2013 Step by Step——使用自定义的List Template
  13. 错误处理之异常与返回码
  14. 因果法制体系轮回框架的崛起
  15. matlab对角替换,matlab矩阵对角最大化实现
  16. 10个让你相见恨晚的iOS Swift动画框架!
  17. 开源社已加入群聊,思否 AIGC Hackathon 扩列
  18. CAD怎么调整绘图区左下方显示坐标的框
  19. MATLAB实现中频正交采样(数字下变频)
  20. 机器人专业需要学习那些理论知识

热门文章

  1. dog log 算子_log算子和dog算子
  2. OpenSSL之X509证书用法
  3. 进去springstrap显示无响应_何为优秀显示器?显示器参数标准主观讨论
  4. ZooKeeper典型应用场景
  5. 2011年12月13日 timeout 与 refused windows clipbrd
  6. PCB检查流程checklist
  7. 数学建模冲刺篇(灵敏度分析)
  8. Palabos User Guide中文解读 | 第十四章 | 网格加密Refinement
  9. Fluent动网格知识汇总
  10. 数据结构与算法分析(五)队列