我在理解TLS/SSL如何在电子邮件中工作时遇到一些问题。SMTP TLS证书
我有一些问题。
- 在我的机器,如果我调试下面的代码角落找寻未能在第一时间对“sslSocket.startHandshake()”行,但如果我再次尝试马上它工作正常。
我得到的错误消息是:“握手期间远程主机关闭连接”。
当我将相同的代码部署到暂存环境并发送电子邮件时,代码第一次正常工作。 开发和登台服务器都在同一个网络中,都没有防病毒程序运行。
我唯一能想到的就是为什么它不是第一次在开发环境中工作,是因为我正在使用调试器逐步执行代码,并且因为这样做速度较慢。
您对我为什么收到此错误有任何了解吗?
- 下面的代码创建一个SSL套接字。我很想知道这个代码是否足以与邮件服务器建立连接。这些SSLSocketFactory类是否自己处理证书?
2a)还是我仍然需要指定一个证书?
2b)或者是这个代码从服务器获取证书并使用证书来加密数据并将加密数据来回发送到电子邮件服务器?
我知道它应该像这里描述的那样工作: RFC 3207定义了SMTP连接如何使用加密。建立连接后,客户端发出STARTTLS命令。如果服务器接受这一点,则客户端和服务器协商加密机制。如果协商成功,随后在它们之间传递的数据将被加密。
2c)下面的代码是否在执行此操作?
socket.setKeepAlive(true);
SSLSocket sslSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(
socket,
socket.getInetAddress().getHostAddress(),
socket.getPort(),
true);
sslSocket.setUseClientMode(true);
sslSocket.setEnableSessionCreation(true);
sslSocket.setEnabledProtocols(new String[]{"SSLv3", "TLSv1"});
sslSocket.setKeepAlive(true);
// Force handshake. This can throw!
sslSocket.startHandshake();
socket = sslSocket;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
非常感谢您对这个非常详细的解释 - 这非常有帮助。 对于第1点,基础套接字已打开,但在事务失败或成功后关闭。所以我不认为这会影响第二次尝试,因为这是一个全新的套接字。 – Leo
也谢谢你提示删除setEnabledProtocols()函数。我正在使用Java 8,所以我删除了它。在接下来的几个月里,我将创建一个电子邮件服务器,然后我可以更轻松地看到服务器端正在做什么,这样我就可以确定第一次握手时出了什么问题。有趣的是,代码正在第一次在我们的分段环境中工作。 再次感谢您的帮助! – Leo