2012-10-05 16 views
12

我已經編寫了以下代碼,用於通過SMTP發送使用javamail API的電子郵件作爲TLS,因爲SSL不受支持,但我結束了除了以下例外。請參閱下面的代碼。我已經使用了調試模式,在代碼下面還可以找到異常。無法使用SMTP發送電子郵件(獲取javax.mail.MessagingException:無法將套接字轉換爲TLS;)

import java.util.Properties; 
import javax.mail.Message; 
import javax.mail.MessagingException; 
import javax.mail.PasswordAuthentication; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeMessage; 

public class SendMailTLS { 

    public static void main(String[] args) { 

     final String username = "[email protected]"; 
     final String password = "***********"; 

     Properties props = new Properties(); 
     props.put("mail.smtp.auth", "true"); 
     props.put("mail.smtp.starttls.enable", "true"); 
     props.put("mail.smtp.host", "mail.mydomain.com"); 
     props.put("mail.smtp.debug", "true"); 
     props.put("mail.smtp.port", "587"); 

     Session session = Session.getInstance(props, 
      new javax.mail.Authenticator() { 
      protected PasswordAuthentication getPasswordAuthentication() { 
       return new PasswordAuthentication(username, password); 
      } 
      }); 
     session.setDebug(true); 

     try { 

      Message message = new MimeMessage(session); 
      message.setFrom(new 
        InternetAddress("[email protected]")); 
      message.setRecipients(Message.RecipientType.TO, 
      InternetAddress.parse("[email protected]")); 
      message.setSubject("Testing Subject"); 
      message.setText("Dear Mail Crawler," 
       + "\n\n No spam to my email, please!"); 

      Transport.send(message); 

      System.out.println("Done"); 

     } catch (MessagingException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

異常跟蹤

DEBUG: setDebug: JavaMail version 1.4.5 
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc] 
DEBUG SMTP: useEhlo true, useAuth true 
DEBUG SMTP: useEhlo true, useAuth true 
DEBUG SMTP: trying to connect to host "mail.mydomain.com", port 587, isSSL false 
220-cpanel35.per.syra.net.au ESMTP Exim 4.80 #2 Fri, 05 Oct 2012 17:28:56 +0800 
220-We do not authorize the use of this system to transport unsolicited, 
220 and/or bulk e-mail. 
DEBUG SMTP: connected to host "mail.mydomain.com", port: 587 

EHLO xxxxxx.xxxxx.com 
250-cpanel35.per.syra.net.au Hello xxxx.xxxxx.com [xx.xx.xx.xxx]i 
250-SIZE 52428800 
250-8BITMIME 
250-PIPELINING 
250-AUTH PLAIN LOGIN 
250-STARTTLS 
250 HELP 
DEBUG SMTP: Found extension "SIZE", arg "52428800" 
DEBUG SMTP: Found extension "8BITMIME", arg "" 
DEBUG SMTP: Found extension "PIPELINING", arg "" 
DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN" 
DEBUG SMTP: Found extension "STARTTLS", arg "" 
DEBUG SMTP: Found extension "HELP", arg "" 
STARTTLS 
220 TLS go ahead 
Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Could not convert socket to TLS; 
    nested exception is: 
    javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair 
    at SendMailTLS.main(SendMailTLS.java:52) 
Caused by: javax.mail.MessagingException: Could not convert socket to TLS; 
    nested exception is: 
    javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair 
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1918) 
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:652) 
    at javax.mail.Service.connect(Service.java:317) 
    at javax.mail.Service.connect(Service.java:176) 
    at javax.mail.Service.connect(Service.java:125) 
    at javax.mail.Transport.send0(Transport.java:194) 
    at javax.mail.Transport.send(Transport.java:124) 
    at SendMailTLS.main(SendMailTLS.java:47) 
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) 
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868) 
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1826) 
    at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1809) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1328) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1305) 
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:548) 
    at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:485) 
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1913) 
    ... 7 more 
Caused by: java.lang.RuntimeException: Could not generate DH keypair 
    at sun.security.ssl.DHCrypt.<init>(DHCrypt.java:123) 
    at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:618) 
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:202) 
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) 
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1321) 
    ... 11 more 
Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive) 
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120) 
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:658) 
    at sun.security.ssl.DHCrypt.<init>(DHCrypt.java:117) 
    ... 18 more 

誰能幫我調試呢?提前致謝!

回答

9

我剛好在評論下方財產

props.put("mail.smtp.starttls.enable", "true"); 

解決了這個問題,並在代碼中沒有錯誤或警告得到執行或者乾脆刪除從上面的源代碼這一行。它像一個魅力直到日期。

+0

換句話說,將此屬性設置爲mail.smtp.starttls.enable = false –

+12

換句話說,您的密碼以純文本的形式通過互聯網傳播。非常糟糕的建議。 – dschulz

+0

是的,這沒有加密。它也可能會將您的電子郵件作爲垃圾郵件發送。 – santafebound

2

看起來您的服務器使用的SSL實現與您正在使用的JDK版本中的SSL實現不兼容。文件SSLNOTES.txt(也包含在JavaMail下載包中)提供了一些調試技巧。你可能需要一個JDK SSL專家來解決這個問題。

+0

感謝您的回覆比爾。 –

1

如果你不希望使用SSL,並且您正在使用SMTP,而不是SMTPS嘗試這些設置

mail.smtp.starttls.enable=false 
mail.transport.protocol=smtp 
1

我有這個問題。原因是我們的管理員阻止了TLS和SSL協議。

3

確保您的防病毒軟件不阻止應用程序。在我的情況下,Avast阻止我在Java SE應用程序中發送電子郵件。

+1

請張貼英文答案 – msrd0

+0

Andre Andrade爲我解決了它!在我的情況下,這是最有用的答案(因爲測試此問題需要1分鐘,所以每個人都應該在浪費其他時間之前嘗試一下) – Jake

8

註釋屬性「mail.smtp.starttls.enable」意味着您回退到默認和不安全的連接,只有遠程SMTP主機也接受端口587上的不安全傳輸(郵件端口提交與端口25或終端交付操作)。在我的上下文中,587是強制性的,任何嘗試打開沒有TLS的會話都會產生SMTP服務器錯誤響應「530必須首先發出STARTTLS命令」。然後將「mail.smtp.starttls.enable」設置爲「true」單獨仍然會產生相同的錯誤「無法將套接字轉換爲TLS」,但現在出現了一條線索:「服務器不可信」。實際上,您必須在JVM啓動屬性中定義一個包含結束於受信任根證書的證書鏈的密鑰庫,或者使用此額外屬性強制信任:「mail.smtp.ssl.trust」設置爲遠程主機名。

配置在JavaMail的,例如(您可以輕鬆地映射到普通的JavaMail API)Spring支持整個東西需要以下所有條件:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> 
<property name="host" value="theRemoteSmtpServer" /> 
<property name="port" value="587" /> 
<property name="username" value="muUserID" /> 
<property name="password" value="myPassword" /> 
<property name="javaMailProperties"> 
    <props> 
     <prop key="mail.smtp.starttls.enable">true</prop> 
     <prop key="mail.smtp.ssl.trust">theRemoteSmtpServer</prop> 
     <prop key="mail.smtp.auth">true</prop> 
    </props> 
</property> 
</bean> 
+0

這對我有效......非常感謝。我試圖在過去的24小時內解決這個問題。最後你的帖子來救我! :) –

+0

這對我有效。我錯過了'mail.smtp.ssl.trust'屬性,並添加它修復了我。謝謝! –

0

堆棧跟蹤表明,問題的真正原因是這個:

java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive) 

你正在運行的老版本的Java的限制,不支持超過1024位的DH素數,你的SMTP服務器可能需要。下面是相關的bug條目:

此限制/限制使用Java 8(見the release notes)已被刪除。

請注意,正如已經指出的那樣,禁用STARTTLS的「修復」並非真正的修復措施:這意味着您的密碼將以純文本的形式發送,而且這僅適用於允許未加密通信的SMTP服務器港口587.

相關問題