我希望这不是重复的。我目前正在使用 Android 上的客户端开发基于 netty 的客户端服务器游戏。我正在尝试创建一个安全的登录过程,所以我尝试在 java 套接字之上使用 ssl。
我设法创建了一个自签名证书并使用了 SSL。问题是我发现的示例源代码使用了一个自定义的 TrustManagerFactory,它不会对证书有效性进行任何检查。由于我不想允许中间人攻击,我搜索了有关 SSL 握手的更多信息,这就是我的理解:
- 为了启动 SSL 会话,客户端向服务器发送请求。
- 拥有证书(.jks 或 .bks)的服务器将公共信息提取到 X509 证书中并将其发送给客户端。
- 客户端检查证书的有效性(在我当前的解决方案中什么都不做)
- 如果检查成功,从证书中检索服务器的公钥,生成一个随机密钥,用公钥加密并将其发送到服务器。
- 服务器使用他的私钥解密随机生成的密钥。
- 客户端和服务器现在共享相同的随机密钥,并使用此密钥进行对称加密(如 AES)开始通信。
除了我自己的服务器,我不需要接受其他任何人的证书,所以我想到了 2 个解决方案:
- 将 X509 保存在客户端并创建一个只接受此证书的自定义 TrustManager。该解决方案似乎易于实施,但很难维护,因为服务器端的每次证书更改都需要更新每个客户端上的 X509 证书。
- 创建我自己的 CA 证书用这个证书签署我的 ssl 证书,并设法让我的客户只信任所有用我的 CA 签署的证书。
我对 CA 身份验证的理解是:
- CA 根证书是包含密钥对的普通证书。
- 使用 CA 签署证书意味着在正在签署的证书的末尾添加使用 CA 私钥加密的整个证书的哈希。
- 此签名包含在 X509 证书中以及有关 CA 的一些信息中。
- 为了检查证书的有效性,客户端生成证书哈希并将其与 X509 证书中包含的解密哈希(使用 CA 公钥)进行比较。
因此,如果我没有弄错所有这些,如果我想实施我的第二个解决方案,我需要向客户提供 CA 证书,以便他可以检查证书。我已经看到可以使用信任库来初始化 à TrustManager。我认为它必须是与根 CA 不同的证书,因为它的整个安全性取决于我的 CA private key 的机密性。所以我的问题是:
- 这个客户端信任库应该包含什么以及如何从我的根 CA 生成?
- 我有红色的 ssl 引擎因自签名证书而损坏。那么我的第二个解决方案在 android 上可行吗?
- 如果这可行,如果我看到有人设法以某种方式获取我的私钥,我该如何使我的证书无效?我有关于 crl 的红色内容,但我不知道如何在我的信任库中生成/使用它们?
提前致谢。