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!
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.
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>
Ich hatte ein ähnliches Problem mit smtp.gmail.com und behebte die folgenden Schritte
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.
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.
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
Ich hatte dieses Problem. Der Grund dafür war, dass unser Administrator die TLS- und SSL-Protokolle blockiert hatte.
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.
Ich habe dieses Problem durch Deaktivieren meines Virenschutzes behoben.
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.