1、引言
在社区中,分享了很多篇基于Netty编写的IM聊天入门文章(比方《跟着源码学IM》系列、《基于Netty,从零开发IM》系列等),在这些文章中分享了各种IM通信算法原理和性能逻辑的实现。然而这样简略的IM聊天零碎是比拟容易被窃听的,如果想要在外面说点悄悄话是不太平安的。怎么办呢?学过密码学的敌人可能就想到了一个解决办法,聊天的时候对音讯加密,解决的时候再对音讯进行解密。是的,情理就是这样。但密码学自身的实践就很简单,加上相干的常识和概念又太多太杂,对于IM入门者来说,想要疾速理清这些概念并实现适合的加解密计划,是比拟头疼的。本文正好借此机会,以Netty编写的IM聊天加密为例,为入门者理清什么是PKI体系、什么是SSL、什么是OpenSSL、以及各类证书和它们间的关系等,并在文末附上简短的Netty代码实示例,心愿能助你通俗易懂地疾速了解这些常识和概念!
补充阐明:本文为了让文章内容尽可能长篇累牍、通俗易懂,尽量不深入探讨各个技术常识和概念,感兴趣的读者能够自行查阅相干材料进一步学习。
学习交换:
- 挪动端IM开发入门文章:《新手入门一篇就够:从零开发挪动端IM》
开源IM框架源码:https://github.com/JackJiang2...(备用地址点此)
(本文已同步公布于:http://www.52im.net/thread-41...)2、相干文章
《即时通讯平安篇(一):正确地了解和应用Android端加密算法》
《即时通讯平安篇(二):探讨组合加密算法在IM中的利用》
《即时通讯平安篇(三):罕用加解密算法与通信平安解说》
《即时通讯平安篇(四):实例剖析Android中密钥硬编码的危险》
《即时通讯平安篇(五):对称加密技术在Android平台上的利用实际》
《即时通讯平安篇(六):非对称加密技术的原理与利用实际》
《即时通讯平安篇(十):IM聊天系统安全伎俩之通信连贯层加密技术》
《即时通讯平安篇(十一):IM聊天系统安全伎俩之传输内容端到端加密技术》3、什么是PKI?
咱们须要先理解一下公钥和私钥的加密规范体系PKI。3.1 基本概念
PKI的全称是Public Key Infrastructure,是指反对公钥管理体制的基础设施,提供甄别、加密、完整性和不可否认性服务。艰深讲:PKI是集机构、零碎(硬件和软件)、人员、程序、策略和协定为一体,利用公钥概念和技术来实现和提供平安服务的、普适性的平安基础设施。在公钥明码中,发送者用公钥(加密密钥)加密,接收者用私钥(解密密钥)解密。公钥个别是公开的,不再放心窃听,这解决了对称明码中的密钥配送问题。然而接收者仍然无奈判断收到的公钥是否非法(有可能是中间人混充的)。事实上,仅靠公钥明码自身,无奈进攻中间人攻打。于是,须要(认证机构)对公钥进行签名,从而确认公钥没有被篡改。加了数字签名的公钥称为公钥证书,个别简称证书。有了证书来认证,能够无效进攻中间人攻打,随之带来了一系列非技术性工作。例如:谁来发证书?如何发证书?不同机构的证书怎么互认?纸质证书作废容易,数字证书如何作废?解决这些问题,须要制订对立的规定,即PKI体系。PKI体系是通过颁发、治理公钥证书的形式为终端用户提供服务的零碎,最外围的元素是证书。围绕证书形成了PKI体系的因素:1)应用PKI的用户;2)颁发证书的机构(Certificate Authority,CA);3)保留证书的仓库。总之:PKI是一个总称,既包含定义PKI的根底规范,也包含PKI的利用规范。3.2 PKI体系现状事实上PKI曾经有两代了。第一代的PKI规范次要是由美国RSA公司的公钥加密规范PKCS、国际电信联盟的ITU-T X.509、IETF的X.509、WAP和WPKI等规范组成。然而因为第一代PKI规范是基于形象语法符号ASN.1进行编码的,实现起来比较复杂和艰难,所以产生了第二代PKI规范。第二代PKI规范是由微软、VeriSign和webMethods三家公司在2001年公布的基于XML的密钥治理标准也叫做XKMS。事实上当初CA核心应用的最广泛的标准还是X.509系列和PKCS系列。X.509系列次要由X.209、X.500和X.509组成,其中X.509是由国际电信联盟(ITU-T)制订的数字证书规范。在X.500根底上进行了性能加强,X.509是在1988年公布的。X.509证书由用户公共密钥和用户标识符组成。此外还包含版本号、证书序列号、CA标识符、签名算法标识、签发者名称、证书有效期等信息。而PKCS是美国RSA公司的公钥加密规范,包含了证书申请、证书更新、证书作废表公布、扩大证书内容以及数字签名、数字信封的格局等方面的一系列相干协定。它定义了一系列从PKCS#1到PKCS#15的规范。其中最罕用的是PKCS#7、PKCS#12和PKCS#10。PKCS#7 是音讯申请语法,罕用于数字签名与加密,PKCS#12是集体音讯替换与打包语法次要用来生成公钥和私钥(题外话:iOS程序员对PKCS#12不生疏,在实现APNs离线消推送时就须要导出.p12证实,正是这个)。PKCS#10是证书申请语法。4、什么是SSL?
4.1 基本概念
SSL(全称 Secure Socket Layer)安全套接层是网景公司(Netscape)率先采纳的网络安全协定。它是在传输通信协议(TCP/IP)上实现的一种平安协定,采纳公开密钥技术。艰深地说:SSL被设计成应用TCP来提供一种牢靠的端到端的平安服务,它不是单个协定,而是二层协定。低层是SSL记录层,用于封装不同的下层协定,另一层是被封装的协定,即SSL握手协定,它能够让服务器和客户机在传输利用数据之前,协商加密算法和加密密钥,客户机提出本人可能反对的全副加密算法,服务器抉择最适宜它的算法。SSL特点是:它与应用层协定独立无关。下层的应用层协定(例如:HTTP、FTP、Telnet等)能通明的建设于SSL协定之上。SSL协定在应用层协定通信之前就曾经实现加密算法、通信密钥的协商以及服务器认证工作。在此之后应用层协定所传送的数据都会被加密,从而保障通信的私密性。
4.2 与TLS的关系SSL是网景公司(Netscape)设计,但IETF将SSL作了标准化,即RFC2246,并将其称为TLS(Transport Layer Security),其最新版本是RFC5246、版本1.2。实际上:TLS是IETF在SSL3.0根底上设计的,相当于SSL的后续版本。所以咱们通常都是SSL/TLS放一起说。5、什么是OpenSSL?
5.1 基本概念
OpenSSL是一个凋谢源代码的软件库,应用程序能够应用这个包来进行平安通信,它包含代码、脚本、配置和过程的汇合。例如:如果您正在编写一个须要简单平安加密的软件,那么只有增加一个平安加密库才有意义,这样您就不用本人编写一大堆简单的加解密函数(而且密码学自身很简单,要写好它们并不容易)。其次要库是以 C 语言所写成,实现了根本的加密性能,实现了 SSL 与 TLS 协定。OpenSSL整个软件包大略能够分成三个次要性能局部:1)SSL协定库;2)应用程序;3)明码算法库。OpenSSL的目录构造天然也是围绕这三个性能局部进行布局的。OpenSSL 能够运行在 OpenVMS、 Microsoft Windows 以及绝大多数类 Unix 操作系统上。5.2 具体来说密钥和证书治理是PKI的一个重要组成部分,OpenSSL为之提供了丰盛的性能,反对多种规范。OpenSSL实现了ASN.1的证书和密钥相干规范,提供了对证书、公钥、私钥、证书申请以及CRL等数据对象的DER、PEM和BASE64的编解码性能。OpenSSL提供了产生各种公开密钥对和对称密钥的办法、函数和应用程序,同时提供了对公钥和私钥的DER编解码性能。并实现了私钥的PKCS#12和PKCS#8的编解码性能。OpenSSL在规范中提供了对私钥的加密爱护性能,使得密钥能够平安地进行存储和散发。在此基础上,OpenSSL实现了对证书的X.509规范编解码、PKCS#12格局的编解码以及PKCS#7的编解码性能。并提供了一种文本数据库,反对证书的治理性能,包含证书密钥产生、申请产生、证书签发、撤消和验证等性能。5.3 倒退历程OpenSSL 打算在 1998 年开始,其指标是创造一套自在的加密工具,在互联网上应用。OpenSSL 以 Eric Young 以及 Tim Hudson 两人开发的 SSLeay 为根底,随着两人返回 RSA 公司任职,SSLeay 在 1998 年 12 月进行开发。因而在 1998 年 12 月,社群另外分支出 OpenSSL,持续开发上来。
▲ 上图为 Tim HudsonOpenSSL 治理委员会以后由 7 人组成有 13 个开发人员具备提交权限(其中许多人也是 OpenSSL 治理委员会的一部分)。只有两名全职员工(研究员),其余的是志愿者。该我的项目每年的估算不到 100 万美元,次要依附捐款。 TLS 1.3 的开发由 Akamai 资助。5.4 下载办法OpenSSL能够从其官网上下载,地址是:https://www.openssl.org/source/,感兴趣的读者能够自行下载安装钻研。6、各类证书
6.1 证书类型操作过证书的敌人可能会对各种证书类型目迷五色,典型的体现就是各种不同的证书扩展名上,一般来说会有DER、CRT、CER、PEM这几种证书的扩展名。
以下是最常见的几种:1)DER文件:示意证书的内容是用二进制进行编码的;2)PEM文件:是一个文本文件,其内容是以“ - BEGIN -” 结尾的,Base64编码的字符;3)CRT和CER文件:基本上是等价的,他们都是证书的扩大,也是文本文件,不同的是CRT通常用在liunx和unix零碎中,而CER通常用在windows零碎中。并且在windows零碎中,CER文件会被MS cryptoAPI命令辨认,能够间接显示导入和/或查看证书内容的对话框;4)KEY文件:次要用来保留PKCS#8规范的公钥和私钥。6.2 罕用OpenSSL命令上面的命令能够用来查看文本证书内容:openssl x509 -incert.pem -text -nooutopenssl x509 -incert.cer -text -nooutopenssl x509 -incert.crt -text -noout上面的命令能够用来查看二进制证书内容:openssl x509 -incert.der -inform der -text -noout上面是常见的PEM和DER互相转换。PEM到DER的转换:openssl x509 -incert.crt -outform der-out cert.derDER到PEM的转换:openssl x509 -incert.crt -inform der -outform pem -out cert.pem补充阐明:上述命令中用到的openssl程序,就是本文中提到的OpenSSL开源库提供的程序。7、Netty中的聊天加密代码示例
7.1 对于Netty
Netty是一个Java NIO技术的开源异步事件驱动的网络编程框架,用于疾速开发可保护的高性能协定服务器和客户端,事实上用Java开发IM零碎时,Netty是简直是首选。无关Netty的介绍我就不啰嗦了,如果不理解那就详读以下几篇:《史上最强Java NIO入门:放心从入门到放弃的,请读这篇!》《Java的BIO和NIO很难懂?用代码实际给你看,再不懂我转行!》《新手入门:目前为止最透彻的的Netty高性能原理和框架架构解析》《史上最艰深Netty框架入门长文:根本介绍、环境搭建、入手实战》基它无关Netty的重要材料:Netty-4.1.x 源码 (在线浏览版)Netty-4.1.x API文档 (在线查阅版)7.2 启动SSL Server代码示例事实上这个题目是不对的,Netty中启动的server还是原来那个server,只是对发送的音讯进行了加密解密解决。也就是说增加了一个专门进行SSL操作的Handler。netty中代表ssl处理器的类叫做SslHandler,它是SslContext工程类的一个外部类,所以咱们只须要创立好SslContext即可通过调用newHandler办法来返回SslHandler。让服务器端反对SSL的代码:ChannelPipeline p = channel.pipeline(); SslContext sslCtx = SslContextBuilder.forServer(...).build(); p.addLast("ssl", sslCtx.newHandler(channel.alloc()));让客户端反对SSL的代码:ChannelPipeline p = channel.pipeline(); SslContext sslCtx = SslContextBuilder.forClient().build(); p.addLast("ssl", sslCtx.newHandler(channel.alloc(), host, port));netty中SSL的实现有两种形式,默认状况下应用的是OpenSSL,如果OpenSSL不能够,那么将会应用JDK的实现。要创立SslContext,能够调用SslContextBuilder.forServer或者SslContextBuilder.forClient办法。这里以server为例,看下创立流程。SslContextBuilder有多种forServer的办法,这里取最简略的一个进行剖析:publicstaticSslContextBuilder forServer(File keyCertChainFile, File keyFile) { returnnewSslContextBuilder(true).keyManager(keyCertChainFile, keyFile);}该办法接管两个参数:1)keyCertChainFile是一个PEM格局的X.509证书文件;2)keyFile是一个PKCS#8的私钥文件。相熟OpenSSL的童鞋应该晓得应用openssl命令能够生成私钥文件和对应的自签名证书文件。具体openssl的操作能够查看我的其余文章,这里就不具体解说了。除了手动创立证书文件和私钥文件之外,如果是在开发环境中,大家可能心愿有一个非常简单的办法来创立证书和私钥文件,netty为大家提供了SelfSignedCertificate类。看这个类的名字就是晓得它是一个自签名的证书类,并且会主动将证书文件和私钥文件生成在零碎的temp文件夹中,所以这个类在生产环境中是不举荐应用的。默认状况下该类会应用OpenJDK's X.509来生成证书的私钥,如果不能够,则应用 Bouncy Castle作为代替。7.3 启动SSL Client代码示例同样的在client中反对SSL也须要创立一个handler。客户端的SslContext创立代码如下:// 配置 SSL.finalSslContext sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();下面的代码咱们应用了一个InsecureTrustManagerFactory.INSTANCE作为trustManager。什么是trustManager呢?当客户端和服务器端进行SSL连贯的时候,客户端须要验证服务器端发过来证书的正确性。通常状况下,这个验证是到CA服务器中进行验证的,不过这样须要一个实在的CA证书环境,所以在测试中,咱们应用InsecureTrustManagerFactory,这个类会默认承受所有的证书,疏忽所有的证书异样。当然:CA服务器也不是必须的,客户端校验的目标是查看证书中的公钥和发送方的公钥是不是统一的,那么对于不能联网的环境,或者自签名的环境中,咱们只须要在客户端校验证书中的指纹是否统一即可。netty中提供了一个FingerprintTrustManagerFactory类,能够对证书中的指纹进行校验。该类中有个fingerprints数组,用来存储平安的受权过的指纹信息。通过比照传入的证书和指纹,如果统一则校验通过。应用openssl从证书中提取指纹的步骤如下:openssl x509 -fingerprint -sha256 -inmy_certificate.crt8、小结一下
下面咱们对Netty聊天用到的加密技术和相干概念进行了梳理,我来简略这些概念之间的关系。
这些概念之间的关系,简略来说就是:- 1)PKI:是一套加密体系和规范的合集,它是实践计划;
- 2)SSL:是利用了PKI理论体系,针对Socket网络这个场景设计的一套平安通信规范,属于是PKI的一个具体利用场景;
- 3)OpenSSL:是PKI体系及SSL规范的算法和代码实现,它包含了具体的开源代码、工具程序等;
4)各种证书:是在SSL或其它基于PKI体系的平安协定规范中须要应用的到一些加密凭证文件等。
而具体到Netty中的聊天加密,那就是利用了上述的PKI体系,基于SSL协定,在OpenSSL等开源库的帮忙下实现的平安程序。9、参考资料
[1] 公钥基础设施(PKI)国际标准停顿
[2] 一篇文章让你彻底弄懂SSL/TLS协定
[3] 什么是OpenSSL?它有什么用处
[4] OpenSSL是什么软件
[5] netty系列之对聊天进行加密
[6] 跟着源码学IM
[7] 基于Netty,从零开发IM
[8] TCP/IP详解(全网惟一在线浏览版)
[9] 疾速了解TCP协定一篇就够
[10] Netty-4.1.x 源码(在线浏览版)
[11] Netty-4.1.x API文档(在线版)
(本文已同步公布于:http://www.52im.net/thread-41...)