Security 未经验证的SSL加密(类似于SSH)

Security 未经验证的SSL加密(类似于SSH),security,networking,ssl,client-server,ssl-certificate,Security,Networking,Ssl,Client Server,Ssl Certificate,我正在用java构建一个网络身份验证系统。 我想用SSL加密我的连接,所以我使用SSLServerSocket。 我已经用keytool生成了一个密钥库:(在ssl目录中) 然后在我的服务器类中: System.setProperty("javax.net.ssl.keyStore", "ssl/myKeystore"); System.setProperty("javax.net.ssl.keyStorePassword", "123456"); 然后在我的客户中: System.setPr

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

然后在我的服务器类中:

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密钥文件代替密钥库吗?

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

通过在客户机上设置与服务器上的密钥库匹配的信任库,可以使客户机信任服务器的公钥(在其证书内)

这相当于SSH预加载了可信服务器密钥指纹。大多数SSH客户端将在您建立第一个连接时学习服务器的公钥或其指纹(原则上,您要手动验证此指纹):您可以使用Java中的SSL/TLS实现这一点,这或多或少是可以做到的

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

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

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

这也可以通过使用客户端证书身份验证的SSL/TLS实现

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


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

如果没有证书,则无法执行SSL。您可以在初始握手中绕过身份验证;但证书也用于加密密钥。也许会告诉你你想做什么。@PeterRitchie证书不用于加密。SSL使用在两端独立生成的对称会话密钥。@ejp证书中的密钥可用于加密。。。很可能是谈判的一部分。而且,如果没有至少一个证书,您不能使用任何SSL(包括加密)。也就是说,没有初始证书,对等方无法协商加密算法或交换新密钥。@PeterRitchie服务器证书中的公钥可由客户端用于加密每一主密钥,也可不用于加密,具体取决于协商的密码套件,这与“也用于加密密钥”不同。他们不是。您的评论的其余部分从来没有争议。@ejp语义,我想;我从来没有暗示有一个单一的(例如)加密,只是说它们“用于加密”。我实际上不在乎使用SSL。实际上,我的理想方案是让服务器端在第一次安装时生成SSL证书,然后让客户端信任任何证书(我已经知道如何信任后者)。我不担心MITM,因为客户端在连接时首先被请求进行身份验证,并且连接已经是安全的。此外,我不能使用keytool生成证书,因为我的项目也将嵌入Android等设备中,而没有完整的java安装,因此我需要一种方法来加密连接或在运行时生成证书。“我不担心MITM,因为客户端在连接时首先被请求进行身份验证,而连接已经是安全的。”。那么,什么保证了连接的安全?
System.setProperty("javax.net.ssl.trustStore", "ssl/myKeystore");
System.setProperty("javax.net.ssl.trustStorePassword", "123456");