Search code examples
javaspring-bootoutlooksmtp

Unsupported or unrecognized SSL message


I am trying to send emails from outlook email in Java+ springboot.

below are the configuration:

@Service
public class EmailService {

    
    String  from_address = "no-reply@jpmorganchase.com",
            password = "somepassword!sd#",
            host = "smtp.office365.com",
            port = "587",
            to_address = "no-reply@jpmorganchase.com",
            mail_subject = "Test",
            mail_content = "testing mail",
             username="",
            user_password="";
    
    
     public void sendmail(UserBean user,String uname, String pword)
        {
            username=uname;
            user_password=pword;
            to_address= user.getEmail();
            Properties props = new Properties();
            props.put("mail.smtp.user", from_address);
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", port);
            props.put("mail.smtp.starttls.enable","true");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.debug", "true");
            props.put("mail.smtp.socketFactory.port", port);
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.fallback", "false");
            mail_content = 
                     "Hello "+user.getName()+"\n"
                            +"Experience "+user.getExperience()+"\n"
                            + "Email "+user.getEmail()+"\n"
                            + "Set allocated: "+user.getSet()+"\n"
                            +"Mobile number "+user.getPhone()+"\n"+"\n"
                            + "Your login credentials are: "+"\n"
                            +"User Name: "+username+"\n"
                            +"Password:  " + user_password+"\n"+"\n"
                            + "Click on link to take test   "+"https://www.jpmorganchase.com/en_sg"+"\n" 
                            +  "Message from jpmorganchase"+user.getMessage()+"\n";
                    
            mail_subject = "jpmorganchase Online Assesment Test";
            SecurityManager security = System.getSecurityManager();

            try
            {
                Authenticator auth = new SMTPAuthenticator();
                Session session = Session.getInstance(props, auth);
                session.setDebug(true);
                MimeMessage msg = new MimeMessage(session);
                msg.setText(mail_content);
                msg.setSubject(mail_subject);
                msg.setFrom(new InternetAddress(from_address));
                msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to_address));
                Transport.send(msg);
            }
            catch (Exception mex)
            {
                mex.printStackTrace();
            } 
        }
     
     public void sendConfirmationMail(User user, String confirmationToken)
        {
            Properties props = new Properties();
            props.put("mail.smtp.user", from_address);
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", port);
            props.put("mail.smtp.starttls.enable","true");
            props.put("mail.smtp.ssl.enable","true");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.debug", "true");
            props.put("mail.smtp.socketFactory.port", port);
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.fallback", "false");
            mail_content = 
                     "Hello "+user.getName()+"\n"
                     +"To confirm your account, please click here : "
                        +"http://localhost:8080/jpmorganchase/confirm-account?token="+confirmationToken;
            mail_subject="Complete Registration!";
           // String mail[] = user.getEmail().split("@");
            //to_address = mail[0]+"@gmail.com";
            to_address = user.getEmail();
                            
            SecurityManager security = System.getSecurityManager();

            try
            {
                Authenticator auth = new SMTPAuthenticator();
                Session session = Session.getInstance(props, auth);
                session.setDebug(true);
                MimeMessage msg = new MimeMessage(session);
                msg.setText(mail_content);
                msg.setSubject(mail_subject);
                msg.setFrom(new InternetAddress(from_address));
                msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to_address));
                Transport.send(msg);
            }
            catch (Exception mex)
            {
                mex.printStackTrace();
            } 
        }

}

I am getting the below exception:

DEBUG: setDebug: JavaMail version 1.5.6
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: protocolConnect returning false, host=smtp.office365.com, user=no-reply@jpmorganchase.com,
password=<null>
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.office365.com", port 587, isSSL false
javax.mail.MessagingException: Could not connect to SMTP host: smtp.office365.com, port: 587;
  nested exception is:
  javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
  at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2120)
  at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:712)

Have tried various solutions over internet but no luck.


Solution

  • I've spent the last 2 weeks solving this problem and searching all around. Finally, I managed to put it all together and make it work. I found key part of solution here.


    In short, you need to create SMTPTransport instead of the classic Transport:

    SMTPTransport t = (SMTPTransport)session.getTransport("smtp");
    Socket socket = new Socket(host, port);
    t.connect(socket);
    t.sendMessage(message, message.getAllRecipients());
    

    NOTE:

    You do not need more than these properties:

    properties.setProperty("mail.smtp.host", host);
    properties.put("mail.smtp.port", port);
    properties.put("mail.smtp.starttls.enable", "true");
    properties.put("mail.smtp.ssl.enable", "true");
    

    and this is essential if you are using self-signed certificates

    properties.put("mail.smtp.ssl.trust", host);
    

    If you plan to use smtps, after creating Session you need to add following:

    Session session = Session.getInstance(properties, null);
    ...
    session.setProtocolForAddress("rfc822", "smtps");
    

    and make sure when creating SMTPTransport to get smtps like:

    SMTPTransport t = (SMTPTransport)session.getTransport("smtps");
    

    and all properties need to be defined for smtps protocol:

    when using smtps properties are set as mail.smtps.<prop>

    in general, based on any protocol: mail.<protocol>.<prop>

    properties.setProperty("mail.smtps.host", host);
    properties.put("mail.smtps.port", port);
    properties.put("mail.smtps.starttls.enable", "true");
    properties.put("mail.smtps.ssl.enable", "true");
    properties.put("mail.smtps.ssl.trust", host);