it-swarm.com.de

Senden einer E-Mail mit SMTP nicht möglich (Abrufen von javax.mail.MessagingException: Socket konnte nicht in TLS konvertiert werden.)

Ich habe den folgenden Code zum Senden von E-Mails unter Verwendung der Javamail-API über SMTP als TLS geschrieben, da SSL nicht unterstützt wird, jedoch die folgende Ausnahme auftrat. Bitte sehen Sie meinen Code unten. Ich habe den Debugging-Modus verwendet und unter dem Code finden Sie auch die Ausnahme.

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

Ausnahme-Trace

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

Kann mir jemand helfen, das zu debuggen? Danke im Voraus!

12
Nagarajan S R

Ich habe dieses Problem gelöst, indem ich nur die unten stehende Eigenschaft kommentierte

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

und der Code wurde ohne Fehler oder Warnung ausgeführt oder löscht diese Zeile einfach aus dem obigen Quellcode. Es funktioniert bis heute wie ein Zauber.

11
Nagarajan S R

Wenn Sie die Eigenschaft "mail.smtp.starttls.enable" auskommentieren, bedeutet dies, dass Sie auf eine standardmäßige und ungesicherte Verbindung zurückgreifen. Diese Verbindung funktioniert nur, wenn der Remote-SMTP-Host auch ungesicherten Transport auf Port 587 (Port für E-Mail-Übermittlung und Port 25) akzeptiert für Endzustellungs- oder Relaisbetrieb). In meinem Kontext ist TLS auf 587 obligatorisch, und jeder Versuch, eine Sitzung ohne TLS zu öffnen, führt zu der SMTP-Serverfehlerantwort "530 Muss zuerst einen STARTTLS-Befehl ausgeben". Wenn Sie dann "mail.smtp.starttls.enable" auf "true" setzen, wird immer noch derselbe Fehler ausgegeben. "Socket konnte nicht in TLS konvertiert werden", aber jetzt mit einem Hinweis: "Server ist nicht vertrauenswürdig". In den JVM-Starteigenschaften muss ein Keystore definiert sein, der eine Zertifikatskette enthält, die auf ein vertrauenswürdiges Stammzertifikat endet, oder die Vertrauenswürdigkeit mit dieser zusätzlichen Eigenschaft erzwingen: " mail.smtp.ssl.trust " auf gesetzt der entfernte Hostname.

Wenn Sie beispielsweise die gesamte Spring-Unterstützung für die Unterstützung von Javamail konfigurieren (die Sie ganz einfach der normalen Javamail-API zuordnen können), müssen Sie Folgendes beachten:

<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

Ich hatte ein ähnliches Problem mit smtp.gmail.com und behebte die folgenden Schritte

  1. habe meinen Code gemäß den berhauz-Kommentaren geändert
  2. in den Google Mail-Einstellungen über diesen Link geändert: https://www.google.com/settings/security/lesssecureapps
3

Stellen Sie sicher, dass Ihre Antivirensoftware die Anwendung nicht blockiert. In meinem Fall blockiert Avast mich in einer Java SE-Anwendung für das Senden von E-Mails.

3
André Andrade

Anscheinend ist die von Ihrem Server verwendete SSL-Implementierung nicht mit der SSL-Implementierung in der verwendeten JDK-Version kompatibel. Die Datei SSLNOTES.txt (ebenfalls im JavaMail-Downloadpaket enthalten) enthält einige Tipps zum Debuggen. Möglicherweise benötigen Sie einen JDK-SSL-Experten, um dies zu beheben.

2
Bill Shannon

Wenn Sie kein SSL verwenden möchten und SMTP statt SMTP verwenden, probieren Sie diese Einstellungen

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

Ich hatte dieses Problem. Der Grund dafür war, dass unser Administrator die TLS- und SSL-Protokolle blockiert hatte. 

1
Ehsan Mirsaeedi
session.getProperties().put("mail.smtp.starttls.enable","true");
props.put("mail.smtp.ssl.trust", "smtp.office365.com(site where your account is)");
props.put("mail.smtp.starttls.enable", true);

Diese Codes sollten in der Lage sein, eine ttls-Kommunikation zu starten und den Mail-Dienst zum Laufen zu bringen.

Darüber hinaus erstellt das Virenschutzprogramm eine Firewall, die den Handshake verhindert.

0
Binay Dhawa

Ich habe dieses Problem durch Deaktivieren meines Virenschutzes behoben.

0

Die Stack-Ablaufverfolgung zeigt, dass die eigentliche Ursache des Problems folgende ist:

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

Sie stoßen auf eine Einschränkung älterer Java-Versionen, die DH-Prims nicht länger als 1024 Bit unterstützten, was wahrscheinlich Ihr SMTP-Server benötigte. Hier sind die relevanten Fehlereinträge:

Diese Einschränkung/Einschränkung wurde in Java 8 aufgehoben (siehe die Versionshinweise ).

Wie bereits erwähnt, ist Ihr "Fix" zur Deaktivierung von STARTTLS kein wirklicher Fix: Das bedeutet, dass Ihr Kennwort als Klartext gesendet wird. Außerdem funktioniert dies nur für SMTP-Server, die unverschlüsselten Datenverkehr an Port 587 zulassen.

0
Grodriguez