将 ssl/tls-message 扩展为可重入 Java 程序

问题描述

我将以下问题/解决方案扩展为可重入,以便使用 TLS 加密将后续电子邮件连接/提交到 SMTP 电子邮件服务器(例如 Comcast)。

Unsupported or unrecognized ssl-message exception at startHandshake after issuing STARTTLS command in a java program

我已经成功地研究并设计了 user9191556 的算法并对其进行了修改以用于后续电子邮件。经过多次反复试验,我成功地将他/她的 TLS 加密功能应用于我之前的算法,并且我的代码始终如一地工作......虽然,我认为这是不正确的。 (是的,我缺乏电子邮件服务器连接协议的基础知识,也可以使用参考) 我对握手前的非依赖睡眠(即 100 毫秒)不满意 适用于我的环境,但怀疑它是否适用于一般环境。 我尝试在 TLS 输入流 (sslIn) 上循环以查看它何时“准备好”,但它总是超时。 因此,100 毫秒的睡眠时间。

是否有更正式/正确的方法来管理 inputStreams - Socket 和 SSLSocket 版本?

谢谢 鲍勃·巴克利 科罗拉多州 Castle Rock ... 是的,正在下雪。

    //------------------------------------------------------------------------------
    public class SSLComcastTLSPrototype
    {
      //----------------------------------------------------------------------------
      public static void main(String[] args) throws InterruptedException
      {
        for (int i=0; i<5; ++i)
        {
          System.out.println("----------------------------------------------");
          System.out.println("sendMessage #" + i);
          System.out.flush();
    
          sendMessage(i);
        }
      }
    
      //----------------------------------------------------------------------------
      public static void sendMessage(int msgNum)
      {
        Date        dDate       = new Date();
        DateFormat  dFormat     = DateFormat.getDateInstance(DateFormat.FULL,Locale.US);
        int         SMTPPort    = 587;
        String      SMTPServer  = "smtp.comcast.net";
    
        try (Socket   smtpSocket = new Socket(SMTPServer,SMTPPort);
             DataOutputStream os = new DataOutputStream(smtpSocket.getoutputStream());
             BufferedReader   is = new BufferedReader(new nputStreamReader(smtpSocket.getInputStream ())))
        {
          int i = 0;
          while (! is.ready() && ++i < 10)
            Thread.sleep(100);

          if (! is.ready())
          {
            System.err.println("BufferedReader InputStream Timed Out - Email Failed");
            System.err.flush();
            return;
          }

          new Thread(new ReadInput(is)).start();

          os.writeBytes("EHLO WOPR\r\n");
          os.writeBytes("STARTTLS\r\n");

          SSLContext ctx = SSLContext.getInstance("TLSv1.2");
          ctx.init(null,null,null);

          SSLSocketFactory factory = ctx.getSocketFactory();
          try (SSLSocket sslSocket = (SSLSocket) factory.createSocket(
              smtpSocket,smtpSocket.getInetAddress().getHostAddress(),smtpSocket.getPort(),true))
          {
            String[] suites = sslSocket.getSupportedCipherSuites();
            sslSocket.setEnabledCipherSuites(suites);

            try (DataOutputStream sslOut = new DataOutputStream(sslSocket.getoutputStream());
                   BufferedReader sslIn = new BufferedReader(new InputStreamReader(sslSocket.getInputStream())))
            {
              Thread.sleep(100);

              sslSocket.startHandshake();

              sslOut.writeBytes("EHLO WOPR\r\n");
              sslOut.writeBytes("AUTH LOGIN\r\n");
              sslOut.writeBytes("<encoded username>=\r\n");    // Username,BASE64 encoded
              sslOut.writeBytes("<encoded password>\r\n");     // Password,BASE64 encoded
              sslOut.writeBytes("MAIL From: Joe@Comcast.net\r\n");
              sslOut.writeBytes("RCPT To: JoeCool@Comcast.net\r\n");
              //sslOut.writeBytes("RCPT Cc: <Jim@AnyCompany.com>\r\n");
              sslOut.writeBytes("DATA\r\n");
              sslOut.writeBytes("X-Mailer: Via Java\r\n");
              sslOut.writeBytes("DATE: " + dFormat.format(dDate) + "\r\n");
              sslOut.writeBytes("From: Runway <Runway@Airfield.com>\r\n");
              sslOut.writeBytes("To: Joe Pilot\r\n");
              //sslOut.writeBytes("Cc: CCDUDE <CCPerson@TheirCompany.com>\r\n");
              //sslOut.writeBytes("RCPT Bcc: BCCDude<BCC@InvisibleCompany.com>\r\n");
              sslOut.writeBytes("Subject: Foo Foo\r\n");

              sslOut.writeBytes("MIME-VERSION: 1.0\r\n");
              sslOut.writeBytes("CONTENT-TYPE: TEXT/HTML; charset=\"ISO-8859-1\"\r\n");
              sslOut.writeBytes("CONTENT-transfer-encoding: 7bit\r\n");

              sslOut.writeBytes("\r\n");
              sslOut.writeBytes("<html>\r\n");
              //sslOut.writeBytes("<head>\r\n");
              sslOut.writeBytes("<title>G'day,mate!</title>\r\n");
              //sslOut.writeBytes("</head>\r\n");

              sslOut.writeBytes("Message #" + msgNum + "\r\n\r\n\r\n");

              DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.SHORT);
              sslOut.writeBytes("\r\n");
              sslOut.writeBytes("This is the introduction of my email<br>\r\n");
              sslOut.writeBytes("heading of the Date<br>\r\n");
              sslOut.writeBytes(df.format(new Date()) + "<br><br>\r\n");
              sslOut.writeBytes("</html>\r\n");

              sslOut.writeBytes("\r\n.\r\n");
              sslOut.writeBytes("QUIT\r\n");

              //System.out.println("EMail Message Submitted Successfully");
              //System.out.flush();

              String response;
              while ((response = sslIn.readLine()) != null)
              {
                //System.out.println("response: " + response);
                //System.out.flush();
           
                if (response.contains("recipient invalid domain"))
                {
                  System.err.println("***** Invalid Email Address *****");
                  System.err.flush();
                }              
              }
            }
          }
        }
        catch (NoSuchAlgorithmException | KeyManagementException | IOException | InterruptedException ex)
        {
          Logger.getLogger(SSLComcastTLSPrototype.class.getName()).log(Level.SEVERE,ex);
        }
      }

      //----------------------------------------------------------------------------
      static class ReadInput implements Runnable 
      {
        //--------------------------------------------------------------------------
        private final BufferedReader br;
  
        //--------------------------------------------------------------------------
        public ReadInput(BufferedReader br)
        {
          this.br = br;
        }

        //--------------------------------------------------------------------------
        @Override
        public void run()
        {
          try
          {
            int input;
            String allInput = "";
            while ((input = br.read()) >= 0)
            {
              allInput += (char) input;

              if (allInput.toLowerCase().endsWith("start tls\r\n"))
                break;
            }
          }
          catch (IOException e)
          {
            System.err.println("***** Exception: readInput *****");
            System.err.flush();
            e.printstacktrace();
          }
        }
      }
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)