公钥加密的简单理解和Java的keytool的用途

最近项目中要求实现通信信息加密。现在最流行的加密认证方案就是SSL/TLS了。但是且不说具体的加密算法,单用库实现这个加密流程就不是很容易。原因在于对非对称加密的不了解,或者对Java的keytool不了了解,并且网上找到的资料几乎清一色的都是教如何用keytool生成keystore,而不介绍生成的文件是什么。再者如果要结合Android或者iOS,就会出现更多问题。本文将会粗略的介绍非对称加密和Java的keytool的基本用途。本文并不会详细介绍SSL握手过程,因为这些并不需要自己编程实现。

SSL协议既实现了加密,又实现了对通信方真实性的验证。从是否需要对客户端进行真实性验证,SSL分为单向和双向两种。单向SSL仅需要对服务端的真实性进行认证。这种方式在访问HTTPS加密的邮箱或者网站用于保证网站的真实性。而双向SSL不仅需要对服务端的真实性认证,还需要对客户端的真实性认证。比如使用网上银行不仅要验证所访问的网站的真实性,还要需要导入证书以便验证客户端的真实性。我们现在只考虑单向SSL,即客户端对服务端的真实性进行认证。

SSL握手的秘钥协商阶段是利用公钥加密进行的,而握手完成后正常通信的消息加密是利用对称加密实现的。在单向SSL握手过程中,服务端会向客户端发送它的公钥证书,客户端验证这个公钥证书,确保服务端的真实性,并且用本次握手的随机信息,产生接下来的通信秘钥,用服务端的公钥加密后传送给服务端。服务端使用自己的私钥解密,获得通信秘钥。握手完成后双方用这个通信密钥对消息进行加密通信。

有时我们用HTTPS访问某个URL的时候,浏览器会询问是否要信任网站证书。这可能是因为服务端发送过来的证书不是由权威CA(如VeriSign)数字签名的,或者证书本身已经失效。权威CA是通信双方都信任的一个机构。对于客户端来说,客户端一定会信任权威CA的信息。对于浏览器来说,这个信任的意义在于用户所访问的网站不是一个钓鱼网站。浏览器会获取一些权威CA的公钥。如果一个公钥证书宣称自己是被VeriSign颁发并且数字签名的,那么浏览器就会用VeriSign的公钥去验证。如果验证过程失败,或者这个公钥证书是不被浏览器信任的,则会询问用户是否信任这个证书。

所以在单向SSL中,服务端需要自己的私钥和公钥证书,并且公钥证书需要被数字签名。客户端需要有用于签名服务端证书的公钥,用于验证这个数字签名。

下面简单说一下Java的keytool,更详细的用法请参考Oracle。通常使用Java的keytool生成密钥对的时候,要使用不同的参数来用keytool生成一些文件。通常包含如下三个步骤:

keytool -genkeypair -v -alias ks_alias -keystore keystore.jks

keytool -exportcert -keystore keystore.jks -file selfsigned.cer -alias ks_alias

keytool -importcert -keystore truststore.jks -file selfsigned.cer -alias cert_alias

每个命令都做了什么呢?首先需要明确Java的keystore实际上是一个存放密钥或/和证书的容器,并不是某个具体的密钥或者证书。在第一行我们使用genkeypair参数运行keytool的时候,所生成的文件包含了一个私钥和一个用X509v3自签名证书包含的公钥。注意自签名是用生成的私钥数字签名而不是由权威CA进行签名。这个私钥和公钥证书以别名ks_alias标识。在第二行我们使用exportcert参数运行keytool的时候,需要给keytool输入一个用alias指定的证书,也就是第一行命令中别名指定的keystore,其中包含一个公钥证书。exportcert参数的作用就是导出指定的证书。在第三行我们用这个证书生成了另外一个文件。这个文件将在Java程序中被导入,提取其中的证书,作为truststore。其目的是让客户端信任这个证书。

所以要用Java实现SSL单向认证,在服务端只需要导入keystore.jks,而客户端需要导入truststore.jks。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值