javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) 这个错误通常是由于 SSL/TLS 协议或加密套件配置不正确导致的。以下是一些可能的原因及解决方法:

1. TLS 协议版本不匹配

某些服务器只支持特定版本的 TLS 协议(例如 TLS 1.2 或 TLS 1.3),而您的客户端可能配置为使用不受支持的协议版本。

解决方法:

  • 确保您的 Java 环境支持所需的 TLS 版本。可以在 Java 代码中显式设置 TLS 版本:
Properties props = new Properties();
props.put("mail.smtp.ssl.protocols", "TLSv1.2");
Session session = Session.getInstance(props);

2. 加密套件不匹配

客户端和服务器之间可能没有共同支持的加密套件。

解决方法:

  • 检查并设置合适的加密套件。在 Java 代码中,可以通过设置 https.protocolshttps.cipherSuites 来指定允许的协议和加密套件:
System.setProperty("https.protocols", "TLSv1.2");
System.setProperty("https.cipherSuites", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");

3. Java 版本问题

旧版本的 Java 可能不支持最新的 TLS 协议和加密套件。

解决方法:

  • 确保使用最新版本的 Java。您可以下载并安装最新的 JDK。

4. 服务器端配置问题

服务器可能配置为仅接受特定的客户端或配置。

解决方法:

  • 检查服务器配置是否限制了某些协议或加密套件。联系服务器管理员获取更多信息。

5. 调试和日志

启用调试日志以获取更多详细信息,有助于确定问题的确切原因。

解决方法:

  • 在 Java 代码中启用调试日志:
System.setProperty("javax.net.debug", "all");

综合示例

下面是一个综合示例,展示如何配置邮件发送的 TLS 版本和启用调试日志:

import java.util.Properties;
import javax.mail.Session;
import javax.mail.Message;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendMail {
    public static void main(String[] args) {
        // 启用调试日志
        System.setProperty("javax.net.debug", "all");
        
        // 配置属性
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.163.com");
        props.put("mail.smtp.port", "465");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.smtp.ssl.protocols", "TLSv1.2");

        Session session = Session.getInstance(props, new javax.mail.Authenticator() {
            protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
                return new javax.mail.PasswordAuthentication("your_email@163.com", "your_password");
            }
        });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("your_email@163.com"));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@example.com"));
            message.setSubject("Test Mail");
            message.setText("This is a test mail");

            Transport.send(message);

            System.out.println("Sent message successfully....");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

通过正确配置协议和加密套件,并且启用调试日志,您可以更好地了解 SSL 握手过程中发生的问题并找到解决方法。