0

我正在用java构建一个网络认证系统。我想用 SSL 加密我的连接,所以我使用 SSLServerSocket。我用 keytool 生成了一个密钥库:(在 ssl 目录中)

keytool -genkey -keystore myKeystore -keyalg RSA

然后在我的服务器类中:

System.setProperty("javax.net.ssl.keyStore", "ssl/myKeystore");
System.setProperty("javax.net.ssl.keyStorePassword", "123456");

然后在我的客户中:

System.setProperty("javax.net.ssl.trustStore", "ssl/myKeystore");
System.setProperty("javax.net.ssl.trustStorePassword", "123456");

这行得通,但我不能依赖客户端来制作密钥库。

我的目标是一个类似 SSH 的模型:客户端有一个私钥,它将发送到服务器,服务器使用公钥验证它。

我不能使用简单的 RSA 密钥文件而不是密钥库吗?

4

1 回答 1

1

您似乎在这里混淆了许多方面。尽管 SSH 不依赖 SSL/TLS,但这些概念确实大体相似。

通过在客户端上设置与服务器上的密钥库匹配的信任库,您所做的就是使客户端信任服务器的公钥(在其证书内)。

这是预加载受信任服务器密钥指纹的 SSH 等效项。当您建立第一个连接时,大多数 SSH 客户端将学习服务器的公钥或其指纹(原则上您应该手动验证此指纹):您可以使用 Java 中的 SSL/TLS 来实现这一点,这或多或少是什么Andreas Sterbenz 的 InstallCert可以。

这样做的目的是允许客户端验证服务器的身份(没有它可能会发生 MITM 攻击)。

客户端有一个私钥,它将发送到服务器,服务器使用公钥对其进行验证。

当客户端有一个私钥(它实际使用,但从不发送到服务器)时,它仅用于验证客户端。这样做的目的是允许服务器验证客户端的身份(例如,作为密码身份验证的替代方法)。

这也可以通过 SSL/TLS 使用客户端证书身份验证来完成。

SSH 和 SSL/TLS 在这方面的主要区别(协议除外)是 SSL/TLS 倾向于使用 X.509 证书(其中包含公钥和描述实体身份的附加属性),而 SSH 倾向于使用原始公钥直接地。(那里也有使用 X.509 证书的 SSH 扩展,但它们并不常见。)

在这两种情况下,客户端都需要验证服务器的身份以防止 MITM 攻击。这通常使用公钥基础设施(和 X.509 证书)通过 SSL/TLS 完成,但您也可以在第一次连接时学习密钥,例如 SSH:这需要更多工作(您需要自定义信任管理器) . 一个合理的折衷方案(在受控环境中)是使用客户端上的信任库,预加载服务器的证书。这或多或少是你已经做过的,除了你永远不应该泄露服务器的私钥。 您真的不应该在此处使用相同的密钥库,因为服务器的密钥库将包含其私钥:相反,仅导出证书并将其导入密钥库,您将在另一端用作信任库。

于 2013-02-24T22:32:31.390 回答