问题描述
|
我想用Java编写一个简单的程序,该程序可以通过套接字(而不是java.mail)发送邮件;
我有一些示例,但它不起作用(以下是基本问题):
我应该先将邮件发送到发件人的smtp服务器吗?(可能必须提供真实的用户名和密码)。
我得到了一个直接发送到接收者的smtp服务器的示例。我使用gmail进行测试,但失败了,给出了以下信息:
530 5.7.0 Must issue a STARTTLS command first.
我认为这是因为gmail需要SSL套接字。然后,我得到了一个简单的SSL实施来交换\“ new Socket \”,它再次失败并显示错误信息:
javax.net.ssl.SSLException: Unrecognized SSL message,plaintext connection?
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: Unrecognized SSL message,plaintext connection?
也许SSL使用是错误的?这是SSL代码:
class Java2000TrustManager implements x509trustmanager {
Java2000TrustManager() {
}
public void checkClientTrusted(X509Certificate chain[],String authType)
throws CertificateException {
System.out.println(\"checkClientTrusted...\");
}
public void checkServerTrusted(X509Certificate chain[],String authType)
throws CertificateException {
System.out.println(\"checkServerTrusted\");
}
public X509Certificate[] getAcceptedissuers() {
System.out.println(\"getAcceptedissuers...\");
return null;
}
}
请给我一种成功实施此方法的方法。
解决方法
您在TrustManager中所做的事情实际上会禁用使SSL / TLS连接安全的必要检查(服务器证书的验证)。如果GMail没有默认信任存储区中的CA颁发的证书,我会感到非常惊讶。您不需要更改任何信任设置。
您遇到的问题似乎与
STARTTLS
的用法有关,ѭ3是SMTP命令(因此您可能需要在SMTP规范中阅读有关它的更多信息)。
如此处所述,有两种方法可以在SMTP连接中启用SSL / TLS,尽管它们经常被贴上错误的标签(有些调用\“ TLS \”实际上是\“使用STARTTLS \”):
其中之一是“在连接上”或“在前面”(我不确定这是否有标准术语)。在这种情况下,您需要在交换任何SMTP消息之前建立SSL或TLS连接。对于SMTP,这通常位于端口465上。
另一个是使用STARTTLS
命令在SMTP交换期间切换到TLS(尽管有时实际上也可以与SSLv3一起使用)。在这里,客户端开始使用SMTP命令以纯文本方式与服务器对话,然后发送“ 3”命令并发起TLS握手,以将纯套接字转换为SSL / TLS。 SMTP可以在端口25或587上。
据我所知,Gmail都支持。
如果您不太熟悉TLS握手并将普通套接字转换为SSL / TLS套接字(例如,可以使用ѭ6和ѭ7),那么使用第一种方法可能会更容易:SSL /连接时使用TLS。在这种情况下,只需使用SSLSocket
和SSLSocketFactory
即可启动连接。之后,您无需再使用STARTTLS
(作为SMTP协议的一部分),因为您已经在使用SSL / TLS。
, 该代码实现了X509TrustManager接口。单靠它是没有用的,并且其目的不同于您的目的。如果您需要初始化使用SSL / TLS的套接字,则需要
创建一个SSLSocketFactory,
从SSLSocketFactory创建一个套接字,该套接字在特定端口连接到所需的服务器
就像其他套接字(不受SSL / TLS限制)一样,向套接字写入数据和从套接字读取数据。
相关信息:
Java + SSL教程