javax.net.ssl.SSLHandshakeException:没有合适的协议(协议被禁用或密码套件不合适

Posted

技术标签:

【中文标题】javax.net.ssl.SSLHandshakeException:没有合适的协议(协议被禁用或密码套件不合适【英文标题】:javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate 【发布时间】:2021-08-05 22:09:45 【问题描述】:

我知道有几个关于此错误的问题,但对我没有任何帮助。我有在gmail服务器上发送带有附件的电子邮件的方法,它工作正常。昨天我买了一个新的mac mini m1。我尝试了这种方法来发送电子邮件,但它抛出了这个错误

 public static void sentEmail(String report)  
    BaseTest base = new BaseTest();
    
      
      String to = base.getProps().getProperty("emailTO"); ;//change accordingly  
      final String user = base.getProps().getProperty("emailFROM");//change accordingly  
      final String password = base.getProps().getProperty("emailPassword");//change accordingly  
       
      //1) get the session object     
      Properties properties = System.getProperties();  
      properties.setProperty("mail.smtp.host", "smtp.gmail.com");  
      properties.put("mail.smtp.auth", "true"); 
      properties.put("mail.smtp.port", "587");  
      properties.put("mail.smtp.starttls.enable", "true");
      
      
      Session session = Session.getDefaultInstance(properties,  
       new javax.mail.Authenticator()   
       protected PasswordAuthentication getPasswordAuthentication()   
       return new PasswordAuthentication(user,password);  
         
      );  
         
      //2) compose message     
      try  
        MimeMessage message = new MimeMessage(session);  
        message.setFrom(new InternetAddress(user));  
        message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));  
        message.setSubject("From Mobile Automation Project ");  
          
        //3) create MimeBodyPart object and set your message text     
        BodyPart messageBodyPart1 = new MimeBodyPart();  
        messageBodyPart1.setText("Report");  
          
        //4) create new MimeBodyPart object and set DataHandler object to this object      
        MimeBodyPart messageBodyPart2 = new MimeBodyPart();  
      
        String filename = report;//change accordingly  
        DataSource source = new FileDataSource(filename);  
        messageBodyPart2.setDataHandler(new DataHandler(source));  
        messageBodyPart2.setFileName(filename);  
         
         
        //5) create Multipart object and add MimeBodyPart objects to this object      
        Multipart multipart = new MimeMultipart();  
        multipart.addBodyPart(messageBodyPart1);  
        multipart.addBodyPart(messageBodyPart2);  
      
        //6) set the multiplart object to the message object  
        message.setContent(multipart );  
         
        //7) send message  
        Transport.send(message);  
       
       System.out.println("Report has been sent to: "+ to);  
       catch (MessagingException ex) ex.printStackTrace();  

例外

    javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
    javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1907)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:666)
    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 com.qa.utils.TestUtils.SendEmailTLS(TestUtils.java:228)
    at com.qa.BaseTest.afterSuite(BaseTest.java:153)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:134)
    at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:63)
    at org.testng.internal.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:348)
    at org.testng.internal.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:302)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:351)
    at org.testng.SuiteRunner.run(SuiteRunner.java:286)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1109)
    at org.testng.TestNG.runSuites(TestNG.java:1039)
    at org.testng.TestNG.run(TestNG.java:1007)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:284)
    at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:75)
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:119)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
    at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
    at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
    at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:101)
    at sun.security.ssl.TransportContext.kickstart(TransportContext.java:238)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:394)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:549)
    at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:486)
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1902)
    ... 31 more 

我改变了这个参数

properties.setProperty("mail.smtp.host", "smtp.gmail.com");

到这里

properties.setProperty("mail.smtp.ssl.trust", "smtp.gmail.com");

但是我得到了这个异常

javax.mail.MessagingException: Could not connect to SMTP host: localhost, port: 587;
  nested exception is:
    java.net.ConnectException: Connection refused (Connection refused)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1961)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:654)
    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 com.qa.utils.TestUtils.sentEmail(TestUtils.java:189)
    at com.qa.BaseTest.afterSuite(BaseTest.java:152)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:134)
    at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:63)
    at org.testng.internal.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:348)
    at org.testng.internal.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:302)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:351)
    at org.testng.SuiteRunner.run(SuiteRunner.java:286)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1109)
    at org.testng.TestNG.runSuites(TestNG.java:1039)
    at org.testng.TestNG.run(TestNG.java:1007)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:284)
    at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:75)
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:119)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
    at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)
    at java.net.Socket.connect(Socket.java:606)
    at java.net.Socket.connect(Socket.java:555)
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:321)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:237)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1927)
    ... 31 more

【问题讨论】:

您使用的是哪个客户端库? 我正在使用 javax.mail 在旧的 mac 上这段代码可以正常工作,我又检查了一次:/ 我认为有些东西在 mac mini 上阻塞了 smpt 协议 【参考方案1】:

我有一个类似的问题,它似乎与Deepak's response 有关。关注these instructions 解决了这个问题。

似乎有必要明确设置required 标志和协议:

添加以下设置对我有用:

properties.put("mail.smtp.starttls.required", "true");
properties.put("mail.smtp.ssl.protocols", "TLSv1.2");

我必须补充一点,我在端口 465 上测试了这个,完整的配置看起来像这样

properies.put("mail.smtp.host", "smtp.gmail.com");
properies.put("mail.smtp.port", "465");
properies.put("mail.smtp.auth", "true");
properies.put("mail.smtp.starttls.enable", "true");
properies.put("mail.smtp.starttls.required", "true");
properies.put("mail.smtp.ssl.protocols", "TLSv1.2");
properies.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");

【讨论】:

感谢它的工作并解决了我的问题【参考方案2】:

要解决这个问题,只需升级用于 sendmail 的 java 库。 它对我有用。

【讨论】:

【参考方案3】:

警告这样做有启用 tlsv1 和 tlsv1.1 的风险:

    找到保存 java.security 文件的目录。 在 ubuntu 的情况下:

    /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security

    找到jdk.tls.disabledAlgorithms

    删除TLSv1, TLSv1.1

    重新启动服务器并运行项目以再次尝试发送邮件。

【讨论】:

以上是关于javax.net.ssl.SSLHandshakeException:没有合适的协议(协议被禁用或密码套件不合适的主要内容,如果未能解决你的问题,请参考以下文章