2012-10-05 1288 views
12

He escrito el siguiente código para enviar correos electrónicos usando javamail API a través de SMTP como TLS ya que SSL no es compatible pero terminé con la siguiente excepción. Por favor vea mi código abajo. He usado el modo de depuración y debajo del código también puede encontrar la excepción.No se puede enviar un correo electrónico usando SMTP (Obteniendo javax.mail.MessagingException: No se pudo convertir el socket a 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); 
     } 
    } 
} 

traza Excepción

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 

¿Puede alguien ayudarme a depurar este? ¡Gracias por adelantado!

Respuesta

9

que resuelven este problema acaba de comentar el siguiente propiedad

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

y obtuve el código se ejecuta sin errores o advertencia o simplemente Suprimir esta línea desde el código fuente de arriba. Está funcionando como un encanto hasta la fecha.

+0

En otras palabras, establezca esta propiedad como mail.smtp.starttls.enable = false –

+12

En otras palabras, su contraseña está viajando a través de las internets como texto sin formato. Muy mal consejo. – dschulz

+0

Sí, esto no está encriptado. También es probable que envíe sus correos electrónicos como correo no deseado. – santafebound

2

Parece que la implementación de SSL utilizada por su servidor no es compatible con la implementación de SSL en la versión del JDK que está utilizando. El archivo SSLNOTES.txt (también incluido en el paquete de descarga de JavaMail) tiene algunas sugerencias de depuración. Es posible que necesite un experto en JDK SSL para resolver esto.

+0

Gracias por la respuesta Bill. –

1

Si no desea utilizar SSL, y está usando SMTP en lugar de tratar estos ajustes smtps

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

he tenido este problema. el motivo fue que nuestro administrador había bloqueado los protocolos TLS y SSL.

3

Asegúrese de que su software antivirus no esté bloqueando la aplicación. En mi caso, Avast me impedía enviar correos electrónicos en una aplicación Java SE.

+1

por favor publique las respuestas en inglés – msrd0

+0

Andre Andrade lo resolvió por mí! En mi caso, esta fue la respuesta más útil (y, dado que toma 1 minuto probar este problema, todos deberían intentarlo antes de perder horas en otras cosas) – Jake

8

Comentando la propiedad "mail.smtp.starttls.enable" significa que regresa a una conexión predeterminada y no segura, que solo funcionaría si el host SMTP remoto también acepta transporte no seguro en el puerto 587 (el puerto para correo presentación frente al puerto 25 para operaciones de entrega final o retransmisión). En mi contexto, TLS es obligatorio en 587 y cualquier intento de abrir una sesión sin TLS produce la respuesta de error del servidor SMTP "530 Debe emitir primero un comando STARTTLS". Luego, configurar "mail.smtp.starttls.enable" como "verdadero" solo sigue produciendo el mismo error "No se pudo convertir el socket a TLS", pero ahora con una pista: "El servidor no es de confianza". De hecho, debe tener ya sea un almacén de claves definido en las propiedades de inicio de JVM que contendría una cadena de certificados que finaliza en un certificado raíz de confianza, o imponer la confianza con esta propiedad adicional: "mail.smtp.ssl.trust" establecido en el control remoto nombre de host

Configuración de todo el material de apoyo para la primavera Javamail por ejemplo (que se puede asignar fácilmente a la API JavaMail llanura) requiere que todos los siguientes:

<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

Esto funcionó para mí ... Muchas gracias. Intentaba superar este problema durante las últimas 24 horas. Finalmente tu post vino a mi rescate !! :) –

+0

Esto funcionó para mí. Me faltaba la propiedad 'mail.smtp.ssl.trust' y añadí que me la arregló. ¡Gracias! –

0

El seguimiento de pila revela que la causa real del problema es esto:

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

está ejecutando en una limitación de las versiones antiguas de Java que no apoyaron DH ceba más de 1.024 bits, lo que a su El servidor SMTP probablemente requirió Aquí están las entradas de errores relevantes:

Esta restricción/limitación se eliminó en Java 8 (ver the release notes).

Tenga en cuenta que como ya se señaló, su "solución" de STARTTLS de deshabilitación no es una solución real: significa que su contraseña se enviará como texto sin formato, además esto solo funcionará para servidores SMTP que permiten el tráfico no encriptado puerto 587.

Cuestiones relacionadas