gpt4 book ai didi

java - Java中的 key SSL套接字连接

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:33:25 25 4
gpt4 key购买 nike

我正在加密服务器和客户端之间的tcp连接。在研究和测试过程中,我倾向于使用 secret key 加密。我的问题是我找不到有关如何实现此功能的任何教程。我发现的教程围绕一键式https请求展开,我所需要的只是一个SSL套接字。

我到目前为止编写的代码如下。我几乎可以确定它需要扩展,我只是不知道该怎么做。任何帮助表示赞赏。

private ServerSocketFactory factory;
private SSLServerSocket serverSocket;

factory = SSLServerSocketFactory.getDefault();
serverSocket = (SSLServerSocket) factory.createServerSocket( <portNum> );

接受客户端连接的服务器代码
SSLSocket socket = (SSLSocket) serverSocket.accept();
socket.startHandshake();

我只是不知道如何实际进行握手。

引用: http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html

最佳答案

SSL套接字连接在Java中得到很好的支持,对于您来说可能是一个不错的选择。事先要了解的一件事是SSL同时提供加密和服务器身份验证。您不能轻易获得仅加密。作为引用,加密可防止网络窃听,而服务器身份验证可防止“中间人”攻击,在这种情况下,攻击者充当客户端和服务器之间的代理。

由于身份验证是SSL不可或缺的一部分,因此服务器将需要提供SSL证书,而客户端将需要能够对证书进行身份验证。服务器将需要一个“ keystore ”文件来存储其证书。客户端将需要一个“信任存储”文件,在该文件中存储其信任的证书,其中之一必须是服务器的证书,或者可以从中追溯“信任链”的证书到服务器的证书。

请注意,您不必了解SSL的来龙去脉即可使用Java SSL套接字。我确实认为,通读SSL的工作方式很有意思,例如Wikipedia上有关TLS的文章,但是复杂的多步握手和实际连接加密的设置都由SSLServerSocket和SSLSocket类在幕后处理。

代码

以上所有内容只是背景信息,它解释了以下一些代码。该代码假定您熟悉常规的未加密套接字。在服务器上,您将需要如下代码:

/**
* Returns an SSLServerSocket that uses the specified key store file
* with the specified password, and listens on the specified port.
*/
ServerSocket getSSLServerSocket(
File keyStoreFile,
char[] keyStoreFilePassword,
int port
) throws GeneralSecurityException, IOException {
SSLContext sslContext
= SSLConnections.getSSLContext(keyStoreFile, keyStoreFilePassword);
SSLServerSocketFactory sslServerSocketFactory
= sslContext.getServerSocketFactory();
SSLServerSocket sslServerSocket
= (SSLServerSocket) sslServerSocketFactory.createServerSocket(port);
return sslServerSocket;
}

然后可以像使用其他任何ServerSocket一样完全使用SSLServerSocket。身份验证,加密和解密将对调用代码完全透明。实际上,我自己的代码中的关联函数声明的返回类型仅为纯ServerSocket,因此调用代码不会感到困惑。

注意:如果要将JRE的默认cacerts文件用作 key 存储文件,则可以跳过创建SSLContext的行,并使用 ServerSocketFactory.getDefault()获取ServerSocketFactory。您仍然必须将服务器的公用/专用 key 对安装到 key 存储文件中,在本例中为 cacerts文件。

在客户端上,您将需要如下代码:
SSLSocket getSSLSocket(
File trustStoreFile,
char[] trustStoreFilePassword,
InetAddress serverAddress,
port serverPort
) throws GeneralSecurityException, IOException {
SSLContext sslContext
= SSLConnections.getSSLContext(trustStoreFile, trustStoreFilePassword);
SSLSocket sslSocket
= (SSLSocket) sslContext.getSocketFactory().createSocket
(serverAddress, serverPort);
sslSocket.startHandshake();
return sslSocket;
}

就像服务器代码中的SSLServerSocket一样,这里返回的SSLSocket就像常规的Socket一样使用;进入和退出SSLSocket的I/O是使用未加密的数据完成的,所有加密工作都是在内部完成的。

与服务器代码一样,如果要使用默认的JRE cacerts文件作为信任库,则可以跳过SSLContext的创建,而使用 SSLSocketFactory.getDefault()而不是 sslContext.getSocketFactory()。在这种情况下,仅当服务器的证书是自签名的或不是由主要证书颁发机构之一签发的,才需要安装服务器的证书。此外,为确保您不信任自己信任的证书链中合法发行的证书,而是将其信任的域与尝试访问的域完全不同,则应在该行之后添加以下(未嵌套的)代码您在其中创建 SSLSocket的地方:
    sslSocket.getSSLParameters().setEndpointIdentificationAlgorithm("HTTPS");

如果您使用自己的信任库文件,但信任该文件中一个或多个证书颁发机构颁发的所有证书,或者信任该文件中不同服务器的许多证书,则这也将适用。

证书, keystore 和信任库

现在最困难的部分,或者至少是稍微困难的部分:生成和安装证书。我建议使用Java keytool(最好是1.7版或更高版本)来完成此工作。

如果要创建自签名证书,请首先使用以下命令从命令行生成服务器的 key 对: keytool -genkey -alias server -keyalg rsa -dname "cn=server, ou=unit, o=org, l=City, s=ST, c=US" -validity 365242 -keystore server_key_store_file -ext san=ip:192.168.1.129 -v。替换您自己的名称和值。特别是,此命令为IP地址为192.168.1.129的服务器创建一个 key 对,该 key 对在365242天(即1000年)内到期。如果客户端将通过域名系统查找服务器,请使用类似 san=dns:server.example.com而不是 san=ip:192.168.1.129的东西。有关keytool选项的更多信息,请使用 man keytool

系统将提示您输入 keystore 的密码-或设置 keystore 的密码(如果这是新的 keystore 文件)-并设置新 key 对的密码。

现在,使用 keytool -export -alias server -file server.cer -keystore server_key_store_file -rfc -v导出服务器的证书。这将创建一个 server.cer文件,其中包含带有服务器公共(public) key 的证书。

最后,使用 keytool -import -alias server -file server.cer -keystore client_trust_store_file -v之类的内容将server.cer文件移动到客户端计算机,并将证书安装到客户端的信任存储中。系统将提示您输入信任存储文件的密码。提示将显示“输入 keystore 密码”,因为Java key 工具可同时用于 keystore 文件和信任库文件。请注意,如果您使用的是默认的JRE cacerts文件,我相信初始密码是 changeit

如果您使用的是从公认的证书颁发机构购买的证书,并且您在客户端上使用默认的JRE cacerts文件,则只需将证书安装在服务器的 key 存储文件中即可;您不必弄乱客户端的文件。服务器安装说明应由证书颁发机构提供,或者您也可以再次检查 man keytool以获取说明。

关于套接字,尤其是SSL套接字,存在大量的神秘知识,但是它们实际上非常易于使用。在许多情况下,十行代码将避免需要复杂而脆弱的消息传递或消息队列基础结构。适合您考虑使用此选项。

关于java - Java中的 key SSL套接字连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22737970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com