2012-10-05 11 views
12

Ho scritto il seguente codice per l'invio di e-mail utilizzando javamail API tramite SMTP come TLS come SSL non è supportato ma ho terminato con la seguente eccezione. Si prega di consultare il mio codice qui sotto. Ho usato la modalità di debug e sotto il codice puoi trovare anche l'eccezione.Impossibile inviare un'e-mail utilizzando SMTP (Ottenere javax.mail.MessagingException: Impossibile convertire il socket in 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); 
     } 
    } 
} 

traccia Eccezione

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 

Qualcuno può aiutarmi a eseguire il debug di questo? Grazie in anticipo!

risposta

9

ho risolto questo problema solo commentando la proprietà sotto

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

e il codice ma ho eseguito senza errori o avvertimento o semplicemente eliminare questa riga dal codice sorgente sopra. Funziona come un incantesimo fino ad oggi.

+0

In altre parole, imposta questa proprietà come mail.smtp.starttls.enable = false –

+12

In altre parole, la tua password sta attraversando gli internet come testo normale. Cattivo consiglio. – dschulz

+0

Sì, questo non è crittografato. Probabilmente invierà le tue e-mail come posta indesiderata. – santafebound

2

Sembra che l'implementazione SSL utilizzata dal server non sia compatibile con l'implementazione SSL nella versione del JDK che si sta utilizzando. Il file SSLNOTES.txt (incluso anche nel pacchetto di download JavaMail) ha alcuni suggerimenti per il debug. Potrebbe essere necessario un esperto SSL JDK per risolvere questo problema.

+0

Grazie per la risposta Bill. –

1

Se non si desidera utilizzare SSL, e si sta utilizzando SMTP invece di SMTPS provare queste impostazioni

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

ho avuto questo problema. il motivo era che il nostro amministratore aveva bloccato i protocolli TLS e SSL.

3

Assicurarsi che il software antivirus non stia bloccando l'applicazione. Nel mio caso Avast mi stava impedendo di inviare e-mail in un'applicazione Java SE.

+1

per favore inserisci le risposte in inglese – msrd0

+0

Andre Andrade ha risolto per me! Nel mio caso, questa è stata la risposta più utile (e, poiché ci vuole 1 minuto per testare questo problema, tutti dovrebbero provarlo prima di sprecare ore su altre cose) – Jake

8

Commentando la proprietà "mail.smtp.starttls.enable" significa che si ricorre a una connessione predefinita e non protetta, che funzionerebbe solo se l'host SMTP remoto accetta anche il trasporto non protetto sulla porta 587 (la porta per posta sottomissione rispetto alla porta 25 per le operazioni di consegna finale o relay). Nel mio contesto, TLS è obbligatorio su 587 e qualsiasi tentativo di aprire una sessione senza TLS produce la risposta all'errore del server SMTP "530 Deve prima inviare un comando STARTTLS". Quindi impostare "mail.smtp.starttls.enable" su "true" da solo restituisce lo stesso errore "Impossibile convertire il socket in TLS" ma ora con un indizio: "Il server non è attendibile". In effetti, è necessario che un keystore definito nelle proprietà di avvio JVM contenga una catena di certificati che termina su un certificato radice attendibile, o applica la fiducia con questa proprietà aggiuntiva: "mail.smtp.ssl.trust" impostato sul telecomando nome host.

Configurazione tutta la roba a sostegno primavera per JavaMail per esempio (che si può facilmente mappare pianura API JavaMail) richiede tutti i seguenti:

<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

Questo ha funzionato per me ... Grazie mille. Stavo cercando di superare questo problema per le ultime 24 ore. Finalmente il tuo post è venuto in mio soccorso !! :) –

+0

Questo ha funzionato per me. Mi mancava la proprietà 'mail.smtp.ssl.trust' e l'aggiunta lo aggiustava per me. Grazie! –

0

L'analisi dello stack rivela che la vera causa del problema è questo:

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

si esegue in una limitazione delle vecchie versioni di Java che non supporta DH innesca più di 1024 bit, che il vostro Probabilmente il server SMTP richiedeva. Qui ci sono le voci di bug rilevanti:

Questa restrizione/limitazione è stata rimossa in Java 8 (vedi the release notes).

Si noti che, come già sottolineato, la "correzione" della disattivazione di STARTTLS non è una soluzione reale: significa che la password verrà inviata come testo normale, in più funziona solo per i server SMTP che consentono il traffico non crittografato su porta 587.

Problemi correlati