一、背景
在项目开发过程中,涉及到一个给企业邮箱发送邮件的功能,但在写完相关的邮件发送代码之后,出现问题,邮件发送失败。其中,邮件发送的相关代码如下:
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost("smtp.aliyun.com");
javaMailSender.setPort(465);
javaMailSender.setUsername("xxxx@xxx"); //这里是邮箱的用户名
javaMailSender.setPassword("password"); //这里是邮箱的密码
//相关的属性配置如下:
Properties properties = new Properties();
properties.put("mail.smtp.auth", true);
properties.put("mail.smtp.timeout", 30000);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.socketFactory.port", "465");
properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.put("mail.smtp.starttls.required", "true");
properties.put("mail.smtp.starttls.enable", "true");
javaMailSender.setJavaMailProperties(properties);
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("xxxx@xxx"); //发件人邮箱,与之前的邮箱用户名相同
message.setTo("xxxx@xxx"); //收件人邮箱
message.setSubject("主题:简单邮件");
message.setText("测试邮件内容");
javaMailSender.send(message); //发送邮件
二、问题
测试邮件过程中遇到的问题如下:
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: smtp.aliyun.com, port: 465;
nested exception is:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate). Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: smtp.aliyun.com, port: 465;
nested exception is:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate);
三、过程
由于该问题是在向阿里云企业邮箱发送邮件时出现的,因此第一时间去想是否是阿里云企业邮箱的问题,也试过将发送端口改为80、25这种方式,均未解决现有问题。
后来意识到真正导致发送邮件失败的原因是以下这段错误:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate);
即在SSL握手过程中没有合适的协议,初步定位到SSL协议的问题。
之后的测试主要围绕SSL协议进行开展,也尝试过在spring的配置文件中配置(实际上在发送邮件的属性配置过程中已经进行过这项配置了,所以此问题与该配置无关)
spring.mail.smtp.ssl.enable = true
以上方式都没有效果。
四、原因与解决
之后,我通过[stackoverflow]()上的这篇回答解决了问题,成功地进行了邮件发送。
1.原因
这个问题是由于JDK版本过高引起的,具体来说,我的JDK版本为jdk_1.8.0_291。而在jdk_1.8.0_181之后,JDK对SSL做了限制,禁用了部分协议,导致在一些需要加密协议的地方出现问题,我们只要重新启用即可。
2.解决
具体的做法为找到JDK中的java.security文件(我的文件路径为:/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre/lib/security/),找到如下内容:
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves
删掉其中的SSlv3,TLSv1和TSLv1.1,删完后如下:
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
jdk.tls.disabledAlgorithms=RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves
然后重新启动JAVA项目,即可发送邮件啦。