Не удалось отправить электронное письмо с помощью SMTP (получение javax.mail.MessagingException: невозможно преобразовать сокет в TLS;)
Я написал следующий код для отправки электронной почты с использованием javamail API через SMTP, поскольку TLS, поскольку SSL не поддерживается, но в итоге я получил следующее исключение. См. Мой код ниже. Я использовал режим отладки, и ниже кода вы также можете найти исключение.
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);
}
}
}
Исключительная трассировка
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
Может ли кто-нибудь помочь мне отладить это? Спасибо заранее!
Ответы
Ответ 1
Я решил эту проблему, просто комментируя приведенное ниже свойство
props.put("mail.smtp.starttls.enable", "true");
и код был выполнен без ошибок или предупреждения или просто удалите эту строку из вышеуказанного исходного кода. Он работает как прелесть до даты.
Ответ 2
mail.smtp.starttls.enable
свойства mail.smtp.starttls.enable
означает, что вы вернетесь к подключению по умолчанию и незащищенному соединению, которое будет работать только в том случае, если удаленный узел SMTP также принимает незащищенный транспорт на порту 587
(порт для отправки почты по сравнению с портом 25 для завершения -доставка или эстафета).
В моем контексте TLS является обязательным на 587
и любая попытка открыть сеанс без TLS приводит к ответу об ошибке сервера SMTP. 530 Сначала необходимо выполнить команду STARTTLS.
Тогда установка mail.smtp.starttls.enable
в значение true
одиночку по-прежнему приводит к той же ошибке. Не удалось преобразовать сокет в TLS, но теперь с подсказкой: сервер не является доверенным. Действительно, в свойствах запуска JVM должно быть определено хранилище ключей, которое будет содержать цепочку сертификатов, оканчивающуюся на доверенный корневой сертификат, либо принудительно установите доверие с помощью этого дополнительного свойства: mail.smtp.ssl.trust, установленного на имя удаленного хоста.
Конфигурирование всей поддержки Spring, например, для javamail (которую можно легко сопоставить с простым javamail API) требует всего следующего:
<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>
Ответ 3
Убедитесь, что ваше антивирусное программное обеспечение не блокирует приложение. В моем случае Avast блокировал меня от отправки электронной почты в приложении Java SE.
Ответ 4
У меня была такая же проблема с smtp.gmail.com и исправлена с помощью следующих шагов
Ответ 5
Похоже, что реализация SSL, используемая вашим сервером, несовместима с реализацией SSL в версии используемого вами JDK. В файле SSLNOTES.txt (также включенном в пакет загрузки JavaMail) есть несколько советов по отладке. Для этого вам может понадобиться эксперт JDK SSL.
Ответ 6
Если вы не хотите использовать SSL и используете smtp вместо smtps, попробуйте эти настройки
mail.smtp.starttls.enable=false
mail.transport.protocol=smtp
Ответ 7
У меня была эта проблема. причина в том, что наш администратор заблокировал протоколы TLS и SSL.
Ответ 8
Возможно, эта проблема связана с безопасностью, и smtp.ssl не является доверенным, поэтому проблема возникает.
Я решил эту проблему, просто добавив свойство
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
Теперь у меня все работает нормально.
Ответ 9
Трассировка стека показывает, что фактическая причина проблемы такова:
java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
Вы сталкиваетесь с ограничением более старых версий Java, которые не поддерживают числа DH, превышающие 1024 бит, что, вероятно, требовал ваш SMTP-сервер. Вот соответствующие записи ошибок:
Это ограничение/ограничение было удалено в Java 8 (см. примечания к выпуску).
Обратите внимание, что, как уже указывалось, ваше "исправление" отключения STARTTLS не является настоящим исправлением: это означает, что ваш пароль будет отправлен как обычный текст, плюс это будет работать только для SMTP-серверов, которые разрешают незашифрованный трафик на порт 587.
Ответ 10
Я решил эту проблему, отключив мою антивирусную защиту.
Ответ 11
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);
Эти коды должны быть в состоянии начать связь ttls и запустить почтовый сервис.
В дополнение к этому антивирус создает брандмауэр, который предотвращает рукопожатие.