如何开启mac抓包了SSL双向验证,能抓包吗

SSL双向认证握手过程&2
SSL消息按如下顺序发送:
1.Client Hello
客户发送服务器信息,包括它所支持的密码组。密码组中有密码算法和钥匙大小;
2.Server Hello
服务器选择客户和服务器都支持的密码组到客户。
3.Certificate
服务器发送一个证书或一个证书链到客户端,一个证书链开始于服务器公共钥匙证书并结束于证明权威的根证书。这个消息是可选的,但服务器证书需要时,必须使用它。
4.Certificate request
当服务器需要鉴别客户时,它发送一个证书请求到客户端。在网络程序中,这个消息很少发送。
5.Server key exchange
服务器当发送来的公共钥匙对钥匙交换不是很充分时,发送一个服务器钥匙交换消息。
6.Server hello done
服务器告诉客户完成它的初始化流通消息。
7.Certificate
假如服务器需要一个客户证书时,客户端发送一个证书链。(只有在服务器需要客户证书时)
8.Client key exchange
客户产生用于对称算法的一个钥匙。对RSA客户用服务器公共钥匙加密这个钥匙信息并把它送到服务器。
9.Certificate verify
在网络程序中,这个消息很少发送,它主要是用来允许服务器结束对客户的鉴别处理。当用这个消息时,客户发送用密码函数的数字签名的信息到服务端,当服务端用公共钥匙解密这个消息时,服务器能够鉴别客户。
10.Change cipher spec
客户发送一个消息告诉服务器改变加密模式。
11.Finished
客户告诉服务器它已准备安全数据通信。
12.Change cipher spec
服务器发送一个消息到客户端并告诉客户修改加密模式。
13.Finished
服务器告诉客户端它已准备好安全数据通信。这是client-server握手协议最后一步。
14.Encrypted data
客户同服务器用对称加密算法和密码函数,并用客户发送到服务器的秘密钥匙加密通信。
SSL握手过程:
摘录自《SSL与TLS》
1. 客户端与服务器需要就一组用于保护数据的算法达成一致;
2. 它们需要确立一组由那些算法所使用的加密密钥;
3. 握手还可以选择对客户端进行认证。
1. 客户端将它所支持的算法列表和一个用作产生密钥的随机数发送给服务器;
服务器从算法列表中选择一种加密算法,并将它和一份包含服务器公用密钥的证书发送给客户端;该证书还包含了用于认证目的的服务器标识,服务器同时还提供了一个用作产生密钥的随机数;
客户端对服务器的证书进行验证(有关验证证书,可以参考数字签名),并抽取服务器的公用密钥;然后,再产生一个称作pre_master_secret的随机密码串,并使用服务器的公用密钥对其进行加密(参考非对称加/解密),并将加密后的信息发送给服务器;
客户端与服务器端根据pre_master_secret以及客户端与服务器的随机数值独立计算出加密和MAC密钥(参考DH密钥交换算法)。
5. 客户端将所有握手消息的MAC值发送给服务器;
6. 服务器将所有握手消息的MAC值发送给客户端。&
<img BORDER="0" src="/blog7style/images/common/sg_trans.gif" real_src ="/mwyz/pic/item/61ad833cb80c4c2.jpg" SMALL="0"
ALT="SSL双向认证握手过程&2"
TITLE="SSL双向认证握手过程&2" />
第5与第6步用以防止握手本身遭受篡改。设想一个攻击者想要控制客户端与服务器所使用的算法。客户端提供多种算法的情况相当常见,某些强度弱而某些强度
强,以便能够与仅支持弱强度算法的服务器进行通信。攻击者可以删除客户端在第1步所提供的所有高强度算法,于是就迫使服务器选择一种弱强度的算法。第5步
与第6步的MAC交换就能阻止这种攻击,因为客户端的MAC是根据原始消息计算得出的,而服务器的MAC是根据攻击者修改过的消息计算得出的,这样经过检
查就会发现不匹配。由于客户端与服务器所提供的随机数为密钥产生过程的输入,所以握手不会受到重放攻击的影响。这些消息是首个在新的加密算法与密钥下加密的消息。&
<img BORDER="0" src="/blog7style/images/common/sg_trans.gif" real_src ="/mwyz/pic/item/10de4e728da5cd.jpg" SMALL="0"
ALT="SSL双向认证握手过程&2"
TITLE="SSL双向认证握手过程&2" />
刚才所描述的每一步都需要通过一条或多条握手消息来实现。在此先简要地描述哪些消息与哪几步相对应,然后详细描述每条消息的内容。下图描述了各条消息:
第1步对应一条单一的握手消息,ClientHello.
第2步对应一系列SSL握手消息,服务器发送的第一条消息为ServerHello,其中包含了它所选择的算法,接着再在Certificate消息中发
送其证书。最后,服务器发送ServerHelloDone消息以表示这一握手阶段的完成。需要ServerHelloDone的原因是一些更为复杂的握
手变种还要在Certifacate之后发送其他一些消息。当客户端接收到ServerHelloDone消息时,它就知道不会再有其他类似的消息过来
了,于是就可以继续它这一方的握手。
第3步对应ClientKeyExchange消息。
第5与第6步对应Finished消息。该消息是第一条使用刚刚磋商过的算法加以保护的消息。为了防止握手过程遭到篡改,该消息的内容是前一阶段所有握手
消息的MAC值。然而,由于Finished消息是以磋商好的算法加以保护的,所以也要与新磋商的MAC密钥—起计算消息本身的MAc值。
注意,上图中省略了两条ChangeCipherSpec消息。
SSL记录协议:
在SSL中,实际的数据传输是使用SSL记录协议来实现的。SSL记录协议是通过将数据流分割成一系列的片段并加以传输来工作的,其中对每个片段单独进行
保护和传输。在接收方,对每条记录单独进行解密和验证。这种方案使得数据一经准备好就可以从连接的一端传送到另一端,并在接收到的即刻加以处理。
在传输片段之前,必须防止其遭到攻击。可以通过计算数据的MAC来提供完整性保护。MAC与片段一起进行传输,并由接收实现加以验证。将MAC附加到片段
的尾部,并对数据与MAC整合在一起的内容进行加密,以形成经过加密的负载(Payload)。最后给负载装上头信息。头信息与经过加密的负载的连结称作
记录(record),记录就是实际传输的内容。下图描述了传输过程:&
<img BORDER="0" src="/blog7style/images/common/sg_trans.gif" real_src ="/mwyz/pic/item/e9ab12033dafcd424bfb51ce.jpg" SMALL="0"
ALT="SSL双向认证握手过程&2"
TITLE="SSL双向认证握手过程&2" />
记录头消息:
记录头信息的工作就是为接收实现(receiving
implementation)提供对记录进行解释所必需的信息。在实际应用中,它是指三种信息:内容类型、长度和SSL版本。长度字段可以让接收方知道
他要从线路上这取多少字节才能对消息进行处理,版本号只是一项确保每一方使用所磋商的版本的冗余性检查。内容类型字段表示消息类型。
SSL记录类型:
SSL支持四种内容类型:application_data、alert、handshake和change_cipher_spec。
使用SSL的软件发送和接收的所有数据都是以application_data类型来发送的,其他三种内容类型用于对通信进行管理,如完成握手和报告错误等。
内容类型alert主要用于报告各种类型的错误。大多数alert(警示)用于报告握手中出现的问题,但也有一些指示在对记录试图进行解密或认证时发生的错误,alert消息的其他用途是指示连接将要关闭。
内容类型handshake用于承载握手消息。
即便是最初形成连接的握手消息也是通过记录层以handshake类型的记录来承载的。由于加密密钥还未确立,这些初始的消息并未经过加密或认证,但是其
他处理过程是一样的。有可能在现有的连接上初始化一次新的握手,在这种情况下,新的握手记录就像其他的数据一样,要经过加密和认证。
change_cipher_spec消息表示记录加密及认证的改变。一旦握手商定了一组新的密钥,就发送change_cipher_spec来指示此刻将启用新的密钥。
各种消息协同工作:
正如我们所看到的,SSL是一种分层协议,它以一个记录层以及记录层上承裁的个同消息类型组成。而该记录层又会由某种可靠的传输协议如TCP来承载。下图描述了该协以的结构:
<img BORDER="0" src="/blog7style/images/common/sg_trans.gif" real_src ="/mwyz/pic/item/a35ab13e4d0c12a154e723c9.jpg" SMALL="0"
ALT="SSL双向认证握手过程&2"
TITLE="SSL双向认证握手过程&2" />
一次ssl连接的完整过程:&
<img BORDER="0" src="/blog7style/images/common/sg_trans.gif" real_src ="/mwyz/pic/item/3bd017d7aa7bfbcb.jpg" SMALL="0"
ALT="SSL双向认证握手过程&2"
TITLE="SSL双向认证握手过程&2" />
单向认证:客户端向服务器发送消息,服务器接到消息后,用服务器端的密钥库中的私钥对数据进行加密,然后把加密后的数据和服务器端的公钥一起发送到客户端,客户端用服务器发送来的公钥对数据解密,然后在用传到客户端的服务器公钥对数据加密传给服务器端,服务器用私钥对数据进行解密,这就完成了客户端和服务器之间通信的安全问题,但是单向认证没有验证客户端的合法性。
双向认证:
(1)客户端向服务器发送消息,首先把消息用客户端证书加密然后连同时把客户端证书一起发送到服务器端
(2)服务器接到消息后用首先用客户端证书把消息解密,然后用服务器私钥把消息加密,把服务器证书和消息一起发送到客户端
(3)客户端用发来的服务器证书对消息进行解密,然后用服务器的证书对消息加密,然后在用客户端的证书对消息在进行一次加密,连同加密消息和客户端证书一起发送到服务器端,
(4)到服务器端首先用客户端传来的证书对消息进行解密,确保消息是这个客户发来的,然后用服务器端的私钥对消息在进行解密这个便得到了明文数据。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。博客分类:
去年用tomcat、jboss配置过HTTPS双向认证,那时候主要用的是JDK自带的keytool工具。这次是用httpd + openssl,区别比较大
在网上搜索了很多文章,发现全面介绍的不多,或者就是版本比较旧了。所以把我配置的过程完整地记录下来,以供参考
首先要说明一下,HTTPS涉及到的内容非常繁杂,包括各种术语、命令、算法,我现在也没有完全搞清楚。本文会尽量把我知道的解释一下,但是深入的内容,暂时不打算深究了
httpd: 2.4.4
openssl:1.0.1
os:ubuntu 12.04 LTS
我准备在httpd上配置一个HTTPS双向认证,既向客户端表明自己的身份,也只允许特定的客户端访问。本文说的主要是作为server的角色的配置,至于作为client的配置,最后也会稍微介绍一下,但是不会详细说明
一般来说,互联网站不会去配置双向认证,因为客户端证书的分发和管理会比较麻烦,会把用户挡在门外,所以一般是不能这么做的。当然,像银行等对安全要求很高的网站,也会采用双向认证,比如U盾、安全控件什么的,其实就是固化的客户端证书
但是对于企业应用来说,客户一般是固定的,比如两个已知的系统对接、内部系统集成等。所以在企业应用领域,双向认证还是比较常见的
三、背景知识
证书(Certificate)是HTTPS的核心,但是其实证书并不是一个单一的东西,而是几种技术的综合
为了网络传输的安全,有很多种技术,最主要的是以下3种:
1、加密/解密
避免消息明文传输,对消息进行加密。早期一般是用对称加密算法,现在一般都是不对称加密,最常见的算法就是RSA。在后面的介绍中,也会多次看到RSA这个词
2、消息摘要
这个技术主要是为了避免消息被篡改。消息摘要是把一段信息,通过某种算法,得出一串字符串。这个字符串就是消息的摘要。如果消息被篡改(发生了变化),那么摘要也一定会发生变化(一般是这样的。如果2个不同的消息生成的摘要是一样的,那么这就叫发生了碰撞)
消息摘要的算法主要有MD5和SHA,在证书领域,一般都是用SHA(安全哈希算法)
3、数字签名
数字签名是为了验证双方的身份,避免身份伪造
以上三个技术结合起来,就是在HTTPS中广泛应用的证书(certificate),证书本身携带了加密/解密的信息,并且可以标识自己的身份,也自带消息摘要
四、在httpd中配置单向HTTPS
首先在%HTTPD_HOME%/conf/目录下,修改httpd.conf文件,加载必要的模块
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule socache_dbm_module modules/mod_socache_dbm.so
LoadModule socache_memcache_module modules/mod_socache_memcache.so
LoadModule ssl_module modules/mod_ssl.so
这里的前提是,在编译httpd的时候,已经编译了ssl模块。这个步骤看另一篇文档:
然后再导入默认的SSL配置文件,当然也可以选择不导入,在httpd.conf直接配置。但是导入默认的可以节省很多时间,并且默认的文件是用vhost配置的,不会跟main server冲突,可以算是一种最佳实践
# Secure (SSL/TLS) connections
Include conf/extra/httpd-ssl.conf
&IfModule ssl_module&
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
&/IfModule&
然后打开%HTTPD_HOME%/conf/extra/目录,看一下httpd-ssl.conf,主要有以下几个配置
SSLEngine on
SSLCertificateFile "/usr/local/httpd/conf/server.cer"
SSLCertificateKeyFile "/usr/local/httpd/conf/server.key.pem"
#SSLCACertificateFile "/usr/local/httpd/conf/ca.cer"
#SSLVerifyClient require
#SSLVerifyDepth
只要开启前3个,单向的HTTPS认证就配置好了。后面3个目前先注释掉,是后面双向认证才用到
然后重启一下httpd,会发现报错:
AH00526: Syntax error on line 106 of /usr/local/httpd/conf/extra/httpd-ssl.conf:
SSLCertificateFile: file '/usr/local/httpd/conf/server.cer' does not exist or is empty
这是因为httpd需要一个服务端的私钥(.key.pem),和一个服务端证书(.cer)。前面已经配置了这2个文件的路径,但是还没有创建。下一步就要创建这些文件
五、创建CA(Certificate Authority)
这个CA,也叫“根证书”
服务端做了一个证书,但是这是没有法律效力的,谁都可以自己做证书,就根本达不到安全的目的。所以就要有一个机构,负责来确认服务端的身份,然后统一的签发证书。这样才能有权威性
当浏览器通过HTTPS协议访问一个网站,网站首先会发过来一个自己的证书(certificate)。接下来浏览器就会到权威机构(CA),去验证一下这个证书是不是它签发的。如果是的话,就信任这个网站的证书,继续访问;如果不是的话,要怎么处理就依赖于实现了。一般的浏览器会弹出一个警告,让用户自己决定要不要继续访问。当然直接拒绝也是可以的
现在国际上有3大CA机构,如果是要自己做一个网站的话,如上所述,一般是需要请这些权威机构帮忙签发证书的。现在所有的主流浏览器,默认都安装了这些CA的根证书,所以如果网站的证书是这些权威机构签发的,浏览器就不会发出警告了。比如支付宝,它的证书是由VeriSign签发的,所以访问支付宝,浏览器不会发出警告
这里还有一个链条的关系,比如我有10个子网站,如果每个都要去找CA签发证书,就很麻烦。我可以找CA给我签发一个次级根证书,然后再用这个次级根证书给自己签发10个证书。那么只要客户的浏览器里有CA根证书就可以了,这10个证书都可以通过认证,不要求客户安装次级根证书,原文见下:
引用Intermediate CA certificates lie between the root CA certificate (which is installed in the browsers) and the server certificate (which you installed on the server).
如果是企业应用,那完全可以自己给自己当CA,因为可以要求目标用户(系统)安装自己的CA根证书,效果是一样的,还可以省下请权威CA签发证书的费用(互联网应用分发自己的CA到无数的互联网用户上,难度很大)
下面就介绍如何创建自己的CA
1、准备工作
先在随便一个目录,创建以下几个子目录:
/private
/certificates
其中private放的是私钥和CSR(后面会介绍),certificates里放的就是证书了
2、创建CA私钥
openssl genrsa -aes256 -out private/ca.key.pem 2048
最后的参数是RSA密钥的长度,默认是512。2048其实长了一点,老的浏览器稍后会不支持,不过现在的主流浏览器都是支持的,所以问题不大
通过这个命令,私钥就创建好了,文件名是ca.key.pem
用这个命令,可以看一下刚才创建的这个私钥的信息
openssl rsa -noout -text -in private/ca.key.pem
不过基本上,看也是白看,反正我是看不懂。只知道私钥里其实有2组数字,是用来形成公钥的,最后也会包含在证书里
引用
A private key contains a series of numbers. Two of these numbers form the "public key", the others are part of the "private key". The "public key" bits are included when you generate a CSR, and subsequently form part of the associated Certificate.
另外,最后的.pem扩展名,是表示该私钥用PEM编码。实际上私钥和证书都是用PEM编码的,PEM只是一种编码格式,不需要太在意。httpd可以直接处理这种编码格式,但是浏览器和JAVA都不行,所以在需要的时候,会把编码从PEM改成PKCS,后面会介绍。只要知道证书和私钥都有编码,只是编码是PEM还是PKCS的区别而已。就像"你好"可以用UTF-8编码,也可以用GBK编码一样,内容是不变的
3、创建CA签名请求
openssl req -new -key private/ca.key.pem -out private/ca.csr -subj "/C=CN/ST=SZ/L=SZ/O=kyfxbl/OU=kyfxbl/CN=*.kyfxbl.net"
这里要注意的是,如果不用-subj参数,那么就会在命令行交互输入签发目标的身份识别信息,这叫DN(Distinguished Name)。其中别的都不要紧,最重要的是CN那一行,因为我这里是根证书,所以我设置为*.kyfxbl.net,这样我后面用这个CA签发的www.kyfxbl.net、game.kyfxbl.net、news.kyfxbl.net……,全都是有效的
生成的签名请求文件,是ca.csr
openssl req -noout -text -in private/ca.csr
同上,看不懂
4、自己签发CA根证书
openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey private/ca.key.pem -in private/ca.csr -out certificates/ca.cer
这里参数很复杂,我也不太清楚准确的意思是什么,可以用openssl x509 -help自己研究一下
生成的ca.cer,就是最终的根证书了!这个文件非常重要,因为后续的服务端证书、客户端证书,都是用这个CA签发的,也要把它分发给客户,让他们导入到自己的浏览器或者系统中
查看的命令是:
openssl x509 -noout -text -in certificates/ca.cer
5、把根证书从PEM编码转为PKCS编码
这步其实不是必选的,但是前面说过,JAVA环境是不能直接用PEM编码的证书的,很多浏览器也不行,所以有时候也需要转一下编码
openssl pkcs12 -export -cacerts -inkey private/ca.key.pem -in certificates/ca.cer -out certificates/ca.p12
得到的ca.p12就是转码后的CA根证书,在不能直接用ca.cer的时候,就用ca.p12代替
六、签发服务端证书
现在CA根证书和私钥都有了,就可以开始签发服务端证书了(签发请求ca.csr是过程文件,有了cer就不再需要它了,要删掉也可以)。下面的命令和签发CA证书时都差不多,但是参数上有区别
1、创建服务端私钥
openssl genrsa -aes256 -out private/server.key.pem 2048
2、创建服务端证书签发请求
openssl req -new -key private/server.key.pem -out private/server.csr -subj "/C=CN/ST=SZ/L=SZ/O=kyfxbl/OU=kyfxbl/CN=www.kyfxbl.net"
和ca.csr的区别在于,这里的CN不是*.kyfxbl.net,而是www.kyfxbl.net,因为我现在是在为www.kyfxbl.net申请证书
3、利用CA根证书,签发服务端证书
openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA certificates/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/server.csr -out certificates/server.cer
这里和前面自己签发CA证书时,参数区别就比较大了,最后得到的server.cer,就是服务端证书
七、测试单向认证
把server.key.pem和server.cer拷贝到%HTTPD_HOME%/conf/目录下,然后重新启动httpd,会要求输入一个密码
然后访问http://localhost:443/,会报400错误:
接下来用https://localhost:443来访问,浏览器报警:
这里就是前面创建CSR时,输入的CN的作用,这个证书是为www.kyfxbl.net申请的,这里请求的地址却是localhost,不匹配所以报错。为了能用www.kyfxbl.net这个主机名来访问,就需要改一下/etc/hosts文件:
127.0.0.1&&&&&& localhost
192.168.1.102&& www.kyfxbl.net
然后就可以用www.kyfxbl.net来访问了,再试一下:https://www.kyfxbl.net/
这次浏览器还是告警,但是告警信息变了:
证书信息如下:
可以看到这个证书是由*.kyfxbl.net这个CA颁发的,浏览器不认识,所以不信任由这个CA签发的所有证书。接下来就需要把ca.cer导入浏览器。这里直接导入server.cer也是可以的,但是后面如果又创建一个网站比如说www2.kyfxbl.net,那么又不行了。所以最好的办法是直接导入CA根证书,那么后续只要是用这个根证书签发的证书,浏览器都会信任
再次访问,可以看到成功了,浏览器不告警,并且URL栏前面打了一个绿勾
八、配置双向认证
如果要配置服务器只允许合法的用户访问,就需要配置双向认证
配置为双向认证之后,除了服务端要发证书给客户端之外,客户端也要发客户端证书到服务端,服务端认证通过,才允许访问
SSLCACertificateFile "/usr/local/httpd/conf/ca.cer"
SSLVerifyClient require
SSLVerifyDepth
在单项认证的基础上,再配置以上3个参数
SSLCACertificateFile,这个意思是当客户端发来客户端证书的时候,httpd用哪个CA根证书校验它
配置好了,还不能重启,因为现在客户端证书还没做好
这里要说明一下,客户端证书是怎么来的
有2种方式:
第一种,客户端也自己CA,然后签发证书给自己。把客户端的CA根证书发过来,配置成SSLCACertificateFile。这在互联网应用里基本是不可能的,安全和管理都是问题。但是在企业应用里,还是比较常见的,双方互相交换CA根证书
第二种,就用刚才服务端的CA根证书,签发一个客户端证书,发给用户,用户每次用这个证书来发请求,像银行,支付宝等等,用的是这种方式
当然理论上其实还有一种办法,就是客户自己去找权威CA签证书,但是这个是不可能的,因为很麻烦,找CA签也非常贵
本文用的是第2种方法。其实都是一样的。关键还是在CA根证书上,所以前面也说过了,CA根证书非常重要
九、签发客户端证书
1、创建客户端私钥
openssl genrsa -aes256 -out private/client.key.pem 2048
2、创建客户端证书签发请求
openssl req -new -key private/client.key.pem -out private/client.csr -subj "/C=CN/ST=SZ/L=SZ/O=kyfxbl/OU=kyfxbl/CN=kyfxbl"
这里的不同在于,这里的CN不是*.kyfxbl.net,也不是www.kyfxbl.net,随便填一个kyfxbl就好了,或者干脆叫user都没问题,反正是一个客户端证书
3、利用CA根证书,签发客户端证书
openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA certificates/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/client.csr -out certificates/client.cer
这里和签发server.cer基本是一样的
4、把客户端证书转换成p12格式
openssl pkcs12 -export -clcerts -inkey private/client.key.pem -in certificates/client.cer -out certificates/client.p12
这步是必须的,因为稍后就需要把客户端证书导入到浏览器里,但是一般浏览器都不能直接使用PEM编码的证书
十、测试双向认证
把ca.cer拷贝到%HTTPD_HOME%/conf/目录下,重启httpd
然后再次访问https://www.kyfxbl.net/,结果这次不是警告,而是直接报错:
接下来要把client.p12导入到浏览器里
导入的时候会要求输入密码,这是为了避免有人偷偷拷贝了别人的客户端证书,伪装成合法用户:
然后再次访问,浏览器会要求选择证书。这个步骤是通过双向认证访问网站时必须的,但是平时访问银行、支付宝的时候貌似没有,这是因为这些网站为了简化用户的操作,都会要求用户安装什么“安全控件”,控件自动选择了证书
点击确定,访问成功!
十一、JKS等
到这里,用httpd配置双向HTTPS认证就完成了
本文说的是作为server的角色,要如何配置。但是在JAVA环境下,如果要以client的角色,通过双向认证发起请求,则还有些不同
这里实际上是要充当一个类似浏览器的角色,需要校验server certificate,还需要在发起请求的时候,把client certificate发过去
在JAVA里,是通过keystore和truststore来实现的,不在本文的讨论范围内。可以看一下其他的几篇博客,在HTTPS分类里
十二、参考资料
《JAVA加密与解密的艺术》——作者梁栋
浏览 14666
论坛回复 /
(0 / 5372)
浏览: 1143278 次
来自: 深圳
http://archive.apache.org/dist/ ...
好文章,解决了大问题!
不错,值得借鉴
赞!!!!!!
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'用户名:csuwzc
文章数:45
访问量:19212
注册日期:
阅读量:1297
阅读量:3317
阅读量:582868
阅读量:467828
51CTO推荐博文
在实际生产环境下,使用RMI实现JMX会受到来自防火墙的诸多限制,替代的方案就是使用JMXMP协议。核心代码实现如下:JMX服务端:&&&&&&&&final&String&protocol&=&"jmxmp";
&&&&&&&&final&String&host&=&"192.168.1.6";
&&&&&&&&final&int&port&=&12345;
&&&&&&&&final&String&serverKeyStoreFile&=&appBase&+&"/config/jmxkey/server.keystore";&&
&&&&&&&&final&String&serverKeyStorePwd&=&"storepass";&&
&&&&&&&&final&String&serverKeyPwd&=&"keypass";&&
&&&&&&&&final&String&serverTrustKeyStoreFile&=&appBase&+&"/config/jmxkey/servertrust.keystore";&&
&&&&&&&&final&String&serverTrustKeyStorePwd&=&"truststorepass";&&
&&&&&&&&//&创建MBeanServer
&&&&&&&&MBeanServer&mbs&=&ManagementFactory.getPlatformMBeanServer();
&&&&&&&&//&创建并注册MBean
&&&&&&&&final&String&domain&=&"app";
&&&&&&&&final&String&className&=&AppInfo.class.getName();
&&&&&&&&final&String&name&=&domain&+&":"&+&"name="&+&classN
&&&&&&&&final&ObjectName&objectName&=&ObjectName.getInstance(name);
&&&&&&&&mbs.createMBean(className,&objectName);
&&&&&&&&//&创建SSLSocketFactory
&&&&&&&&KeyStore&serverKeyStore&=&KeyStore.getInstance("JKS");
&&&&&&&&serverKeyStore.load(new&FileInputStream(serverKeyStoreFile),
&&&&&&&&&&&&&&&&serverKeyStorePwd.toCharArray());
&&&&&&&&KeyStore&serverTrustKeyStore&=&KeyStore.getInstance("JKS");
&&&&&&&&serverTrustKeyStore.load(new&FileInputStream(serverTrustKeyStoreFile),
&&&&&&&&&&&&&&&&serverTrustKeyStorePwd.toCharArray());
&&&&&&&&KeyManagerFactory&kmf&=&KeyManagerFactory
&&&&&&&&&&&&&&&&.getInstance(KeyManagerFactory.getDefaultAlgorithm());
&&&&&&&&kmf.init(serverKeyStore,&serverKeyPwd.toCharArray());
&&&&&&&&TrustManagerFactory&tmf&=&TrustManagerFactory
&&&&&&&&&&&&&&&&.getInstance(TrustManagerFactory.getDefaultAlgorithm());
&&&&&&&&tmf.init(serverTrustKeyStore);
&&&&&&&&SSLContext&sslContext&=&SSLContext.getInstance("TLSv1");
&&&&&&&&sslContext.init(kmf.getKeyManagers(),&tmf.getTrustManagers(),&null);
&&&&&&&&SSLSocketFactory&ssf&=&sslContext.getSocketFactory();
&&&&&&&&//&创建JMX服务器
&&&&&&&&Map&String,&Object&&env&=&new&HashMap&&();
&&&&&&&&env.put("jmx.remote.profiles",&"TLS");
&&&&&&&&env.put("jmx.remote.tls.socket.factory",&ssf);
&&&&&&&&env.put("jmx.remote.tls.enabled.protocols",&"TLSv1");
&&&&&&&&env.put("jmx.remote.tls.enabled.cipher.suites",
&&&&&&&&&&&&&&&&"SSL_RSA_WITH_3DES_EDE_CBC_SHA");
&&&&&&&&JMXServiceURL&url&=&new&JMXServiceURL(protocol,&host,&port);
&&&&&&&&JMXConnectorServer&cs&=&JMXConnectorServerFactory
&&&&&&&&&&&&&&&&.newJMXConnectorServer(url,&env,&mbs);
&&&&&&&&cs.start();JMX客户端:&&&&&&&&final&String&protocol&=&"jmxmp";
&&&&&&&&final&String&host&=&"192.168.1.6";
&&&&&&&&final&int&port&=&12345;
&&&&&&&&final&String&clientKeyStoreFile&=&appBase&+&"/config/jmxkey/client.keystore";&&
&&&&&&&&final&String&clientKeyStorePwd&=&"storepass";&&
&&&&&&&&final&String&foxclientKeyPwd&=&"keypass";&&
&&&&&&&&final&String&clientTrustKeyStoreFile&=&appBase&+&"/config/jmxkey/clienttrust.keystore";&&
&&&&&&&&final&String&clientTrustKeyStorePwd&=&"truststorepass";&&
&&&&&&&&//&创建SSLSocketFactory
&&&&&&&&KeyStore&clientKeyStore&=&KeyStore.getInstance("JKS");&&
&&&&&&&&clientKeyStore.load(new&FileInputStream(clientKeyStoreFile),&clientKeyStorePwd.toCharArray());&&
&&&&&&&&KeyStore&clientTrustKeyStore&=&KeyStore.getInstance("JKS");&&
&&&&&&&&clientTrustKeyStore.load(new&FileInputStream(clientTrustKeyStoreFile),&clientTrustKeyStorePwd.toCharArray());&&
&&&&&&&&KeyManagerFactory&kmf&=&KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());&&
&&&&&&&&kmf.init(clientKeyStore,&foxclientKeyPwd.toCharArray());&&
&&&&&&&&TrustManagerFactory&tmf&=&TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());&&
&&&&&&&&tmf.init(clientTrustKeyStore);&&
&&&&&&&&SSLContext&sslContext&=&SSLContext.getInstance("TLSv1");&&
&&&&&&&&sslContext.init(kmf.getKeyManagers(),&tmf.getTrustManagers(),&null);&&
&&&&&&&&SSLSocketFactory&ssf&=&sslContext.getSocketFactory();
&&&&&&&&//&创建JMX客户端
&&&&&&&&HashMap&String,&Object&&env&=&new&HashMap&&();
&&&&&&&&env.put("jmx.remote.profiles",&"TLS");
&&&&&&&&env.put("jmx.remote.tls.socket.factory",&ssf);
&&&&&&&&env.put("jmx.remote.tls.enabled.protocols",&"TLSv1");
&&&&&&&&env.put("jmx.remote.tls.enabled.cipher.suites",
&&&&&&&&&&&&&&&&"SSL_RSA_WITH_3DES_EDE_CBC_SHA");
&&&&&&&&JMXServiceURL&url&=&new&JMXServiceURL(protocol,&host,&port);
&&&&&&&&JMXConnector&jmxc&=&JMXConnectorFactory.connect(url,&env);
&&&&&&&&MBeanServerConnection&mbsc&=&jmxc.getMBeanServerConnection();
&&&&&&&&//&获取所有的域
&&&&&&&&final&String&domains[]&=&mbsc.getDomains();
&&&&&&&&for&(int&i&=&0;&i&&&domains.&i++)
&&&&&&&&&&&&System.out.println("Domain["&+&i&+&"]&=&"&+&domains[i]);
&&&&&&&&//&调用方法
&&&&&&&&final&String&domain&=&"app";
&&&&&&&&final&String&className&=&AppInfo.class.getName();
&&&&&&&&final&String&name&=&domain&+&":"&+&"name="&+&classN
&&&&&&&&final&ObjectName&objectName&=&ObjectName.getInstance(name);
&&&&&&&&AppInfoMXBean&appInfo&=&JMX.newMBeanProxy(
&&&&&&&&&&&&&&&&mbsc,&objectName,&AppInfoMXBean.class);
&&&&&&&&System.out.println(appInfo.getAppName());
&&&&&&&&System.out.println(appInfo.getAppVersion());
&&&&&&&&jmxc.close();keystore和trustkeystore生成#&生成服务端keystore
keytool&-genkey&-alias&server&-keyalg&rsa&-keysize&1024&-sigalg&sha256withrsa&-keypass&keypass&-keystore&E:\app\config\jmxkey\server.keystore&-storepass&storepass
#&生成客户端keystone
keytool&-genkey&-alias&client&-keyalg&rsa&-keysize&1024&-sigalg&sha256withrsa&-keypass&keypass&-keystore&E:\app\config\jmxkey\client.keystore&-storepass&storepass
#&导出服务端证书
keytool&-export&-alias&server&-keystore&E:\app\config\jmxkey\server.keystore&-storepass&storepass&-file&E:\app\config\jmxkey\server.cer
#&导出客户端证书
keytool&-export&-alias&client&-keystore&E:\app\config\jmxkey\client.keystore&-storepass&storepass&-file&E:\app\config\jmxkey\client.cer
#&创建服务端truststore并导入客户端证书
keytool&-import&-alias&client&-keystore&E:\app\config\jmxkey\servertrust.keystore&-storepass&truststorepass&-file&E:\app\config\jmxkey\client.cer
#&创建客户端truststore并导入服务端证书
keytool&-import&-alias&server&-keystore&E:\app\config\jmxkey\clienttrust.keystore&-storepass&truststorepass&-file&E:\app\config\jmxkey\server.cer参考文献:《jmx rmi 穿越防火墙问题及jmxmp的替代方案》http://blog.csdn.net/yangyan/article/details/7244403《11.4.3 TLS Socket Factory》/cd/E-7609/6mdjrf86r/index.html《Java-JSSE-SSL/TLS编程代码实例-双向认证》http://blog.csdn.net/fw0124/article/details/本文出自 “” 博客,谢绝转载!
了这篇文章
类别:┆阅读(0)┆评论(0)

我要回帖

更多关于 抓包获取短信验证码 的文章

 

随机推荐