web-dev-qa-db-fra.com

Impossible d'envoyer un courrier électronique à l'aide de SMTP (Obtention de javax.mail.MessagingException: impossible de convertir un socket en TLS;)

J'ai écrit le code suivant pour l'envoi d'e-mails à l'aide de l'API javamail via SMTP en tant que TLS car SSL n'est pas pris en charge, mais j'ai obtenu l'exception suivante. S'il vous plaît voir mon code ci-dessous. J'ai utilisé le mode de débogage et sous le code, vous pouvez également trouver l'exception.

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);
        }
    }
}

Trace d'exception

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

Quelqu'un peut-il m'aider à résoudre ce problème? Merci d'avance!

12
Nagarajan S R

J'ai résolu ce problème en commentant simplement la propriété ci-dessous

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

et le code a été exécuté sans erreur ni avertissement ou supprimez simplement cette ligne du code source ci-dessus. Cela fonctionne comme un charme jusqu'à la date.

11
Nagarajan S R

La propriété "mail.smtp.starttls.enable" mise en commentaire signifie que vous revenez à une connexion par défaut non sécurisée, qui ne fonctionne que si l'hôte SMTP distant accepte également le transport non sécurisé sur le port 587 (le port pour l'envoi de courrier par rapport au port 25). pour les opérations de livraison finale ou de relais). Dans mon contexte, TLS est obligatoire sur 587 et toute tentative d'ouverture de session sans TLS génère la réponse d'erreur du serveur SMTP "530 Doit d'abord émettre une commande STARTTLS". Puis définir "mail.smtp.starttls.enable" sur "true" génère toujours la même erreur "Impossible de convertir le socket en TLS", mais maintenant avec un indice: "Le serveur n'est pas approuvé". En effet, vous devez avoir défini un fichier de clés dans les propriétés de démarrage de la machine virtuelle Java qui contiendrait une chaîne de certificats se terminant par un certificat racine approuvé, soit appliquer une approbation avec cette propriété supplémentaire: " mail.smtp.ssl.trust " défini sur le nom d'hôte distant.

Par exemple, pour configurer javamail dans tout le support Spring, vous pouvez facilement mapper celui-ci sur l’API javamail ordinaire. Tous les éléments suivants sont nécessaires:

<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>
10
berhauz

J'ai eu un même problème avec smtp.gmail.com et résolu avec les étapes suivantes

  1. changé mon code selon les commentaires de berhauz
  2. modifié dans les paramètres Gmail à partir de ce lien: https://www.google.com/settings/security/lesssecureapps
3
Sudarsana Kasireddy

Assurez-vous que votre logiciel antivirus ne bloque pas l'application. Dans mon cas, Avast m'empêche d'envoyer des courriels dans une application Java SE.

3
André Andrade

Il semble que l'implémentation SSL utilisée par votre serveur ne soit pas compatible avec celle de la version du JDK que vous utilisez. Le fichier SSLNOTES.txt (également inclus dans le kit de téléchargement JavaMail) contient des astuces de débogage. Vous aurez peut-être besoin d'un expert JDK SSL pour résoudre ce problème.

2
Bill Shannon

Si vous ne souhaitez pas utiliser SSL et que vous utilisez smtp au lieu de smtps, essayez ces paramètres.

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

J'ai eu ce problème. la raison était que notre administrateur avait bloqué les protocoles TLS et SSL. 

1
Ehsan Mirsaeedi

J'ai résolu ce problème en désactivant mon antivirus.

0
sandali chethana

La trace de la pile révèle que la cause réelle du problème est la suivante:

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

Vous rencontrez une limitation d'anciennes versions de Java qui ne prenaient pas en charge les nombres premiers DH supérieurs à 1024 bits, ce que votre serveur SMTP demandait probablement. Voici les entrées de bogue pertinentes:

Cette restriction/limitation a été supprimée dans Java 8 (voir les notes de version ).

Notez que, comme cela a déjà été souligné, votre "solution" de désactivation de STARTTLS n’est pas une solution: cela signifie que votre mot de passe sera envoyé en texte brut. De plus, cela ne fonctionne que pour les serveurs SMTP qui autorisent le trafic non chiffré sur le port 587.

0
Grodriguez