创建信任库以仅验证由JAVA中的自定义CA签名的证书



我希望这不是重复的。我目前正在安卓系统上开发基于netty的客户端-服务器游戏。我试图建立一个安全的登录过程,所以我尝试在java套接字上使用ssl。

我设法创建了一个自签名证书并使用了SSL。问题是,我发现的示例源代码使用了自定义的TrustManagerFactory,它不会对证书有效性进行任何检查。由于我不想允许中间人攻击,我搜索了更多关于SSL握手的信息,我的理解是:

  1. 要启动SSL会话,客户端会向服务器发送一个请求
  2. 拥有证书(.jks或.bks)的服务器将公共信息提取到X509证书中,并将其发送给客户端
  3. 客户端检查证书的有效性(在我当前的解决方案中,什么都不做)
  4. 如果检查成功,则从证书中检索服务器的公钥,生成一个随机密钥,用公钥加密并发送到服务器
  5. 服务器使用他的私钥来解密随机生成的密钥
  6. 客户端和服务器现在共享相同的随机密钥,并使用该密钥开始通信以进行符号加密(如AES)

除了我自己的服务器,我不需要接受任何人的证书,所以我考虑了两个解决方案:

  1. 将X509保存在客户端并创建一个仅接受此证书的自定义TrustManager交换机。这个解决方案似乎很容易实现,但很难维护,因为服务器端的每个证书更改都需要更新每个客户端上的X509证书
  2. 创建我自己的CA证书用这个证书签名我的ssl证书,并设法通知我的客户端只信任所有用我的CA签名的证书

我对CA认证的理解是:

  1. CA根证书是包含密钥对的普通证书
  2. 用CA签名证书意味着在签名证书的末尾添加用CA私钥加密的整个证书的哈希
  3. 此签名包含在X509证书中,以及有关CA的一些信息
  4. 为了检查证书的有效性,客户端生成证书哈希,并将其与X509证书中包含的解密哈希(使用CA公钥)进行比较

因此,如果我没有误解这一切,如果我想实现我的第二个解决方案,我需要向客户端提供CA证书,以便他可以检查证书。我已经看到使用信任库初始化TrustManager是可能的。我认为它必须是一个不同于根CA的证书,因为它的整个安全性取决于我的CA私钥的机密性。所以我的问题是:

  1. 这个客户端信任库应该包含什么,以及如何从我的根CA生成if
  2. 我发现自签名证书的ssl引擎坏了。那么我的第二个解决方案在android上可行吗
  3. 如果这可以工作,如果我看到有人设法获得了我的私钥,我该如何使我的证书无效?我有关于crl的红色东西,但我不知道如何在我的信任库中生成/使用它们

提前谢谢。

我只能回答您的部分问题:

  1. 信任库应该包含您的CA,您可以使用keytool生成它:
    http://docs.oracle.com/cd/E19509-01/820-3503/6nf1il6er/index.html
  2. 毫无疑问,您可以在android中使用java.security.*和org.apache.http.*类以与在java中相同的方式实现这一点。一个警告,对于android版本<2.3,您可能需要实现一个变通方法,因为缺少一些公共CA,而且它不支持未排序的证书链。如果需要,我可以给你更多的细节
  3. 我不知道

编辑:
一篇好文章:
http://nelenkov.blogspot.com/2011/12/using-custom-certificate-trust-store-on.html

最新更新