Using Secure Connection SSL/TLS in JavaMail

Posted by dptr1988 on Mon, 09 Sep 2019 13:25:19 +0200

Secure Connection SSL/TLS in JavaMail

JavaMail now supports the use of SSL/TLS to establish secure connections to access mail servers. In order to simplify secure access, two methods of enabling SSL secure connection are provided:

  1. Configure connection properties
// Here's an example of SMTP enabling SSL secure connections
props.setProperty("mail.smtp.ssl.enable", "true");
  1. Using Secure Connection Protocol
// Non-secure Connection Protocol smtp/pop3/imap in JavaMail
props.setProperty("mail.transport.protocol", "smtp");

// Secure Connection Protocol smtps/pop3s/imaps in JavaMail
props.setProperty("mail.transport.protocol", "smtps");

In addition, IMAP and SMTP protocols support the use of ** "STARTTLS" ** commands (see RFC 2487 and RFC 3501) to switch connections to be protected by TLS. The STARTTLS command is best used when the server supports both SSL and non-SSL connections.

STARTTLS support

STARTTLS support is available in standard "IMAP" and "SMTP" protocols, but must be enabled by setting the appropriate properties "mail.imap.starttls.Enable" or "mail.smtp.starttls.Enable" to "true". When set up, if the server supports the STARTTLS command, it will be used before establishing a connection and sending any login information.

// IMAP Protocol Setup STARTTLS
props.setProperty("mail.imap.starttls.Enable", "true");
// SMTP Protocol Setup STARTTLS
props.setProperty("mail.smtp.starttls.Enable", "true");

Security protocol

When using new protocol names, configuration properties must also use these protocol names. For example, set the property "mail.smtps.host" to the host name of the computer that you want to connect to when using the "smtps" protocol on SMTP on SSL. Similarly, to set the IMAP protocol timeout when using the "IMAPS" protocol for IMAP through SSL, set the property "mail.imaps.timeout". Refer to the package documentation for different protocol packages for the list of available properties, which always use the property name of the form mail to set "mail.".

The Transport.send method uses the default transport protocol "SMTP". If you want to enable SSL secure connection on SMTP protocol, you need to set the attribute "mail.smtp.ssl.enable" to "true". This is usually the easiest way.

props.setProperty("mail.smtp.ssl.enable", "true");

Alternatively, to change the default transport protocol returned by the Session.getTransport.protocol() method to SMTP over secure connection SSL, set the attribute "mail.transport.protocol" to "smtps". To change the transport for the Internet address (returned by the Session.getTransport(Address) method and used by the Transport.send() method), set the protocol using the Session.setProtocolForAddress() method.

// Establish secure connections for security protocols by setting properties
props.setProperty("mail.transport.protocol", "smtps");
// Secure Connection for Internet Address by Setting Session Protocol
session.setProtocolForAddress("rfc822", "smtps");

For other details, please refer to original text

A simple console program is attached for your reference.

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Properties;

/**
 * @author kp
 */
public class Main {

    private static final String TRUE_SYMBOL_Y = "y";

    private static final String MENU_SEND_OPTION = "1";
    private static final String MENU_RECEIVE_OPTION = "2";
    private static final String MENU_EXIT_OPTION = "3";

    public static void main(String[] args) {
        InputStreamReader inputStreamReader = new InputStreamReader(System.in);
        BufferedReader reader = new BufferedReader(inputStreamReader);

        while (true) {
            try {
                System.out.println("\r\n====================== MENU ========================");
                System.out.println("    (1)send        (2)receive        (3)exit");
                System.out.println("====================================================");
                System.out.print("Input option: ");
                String option = reader.readLine();

                if (MENU_SEND_OPTION.equalsIgnoreCase(option)) {
                    send();
                } else if (MENU_RECEIVE_OPTION.equalsIgnoreCase(option)) {
                    receive();
                } else if (MENU_EXIT_OPTION.equalsIgnoreCase(option)) {
                    // Sign out
                    break;
                }

                System.out.flush();
            } catch (Exception e) {
                System.out.println("I/O exception");
                e.printStackTrace();
            }
        }

        System.out.println("\r\nEND!");
    }

    private static void send() throws Exception{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("Please input smtp host: ");
        String host = reader.readLine();
        System.out.print("Please input smtp port: ");
        String port = reader.readLine();
        System.out.print("Please input email address: ");
        String email = reader.readLine();
        System.out.print("Please input email password: ");
        String password = reader.readLine();
        System.out.print("Is SSL(y/n): ");
        String isSsl = reader.readLine();
        String isStartTls = "";
        if (!TRUE_SYMBOL_Y.equalsIgnoreCase(isSsl)) {
            System.out.print("Is SSL(y/n): ");
            isStartTls = reader.readLine();
        }
        System.out.println("################### Message ########################");
        System.out.print("Please input receiver: ");
        String receiver = reader.readLine();
        System.out.print("Please input subject: ");
        String subject = reader.readLine();
        System.out.print("Please input content: ");
        String content = reader.readLine();
        System.out.println("##################### END ##########################");

        // Configure connection parameters
        Properties props = new Properties();
        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtp.host", host);
        props.setProperty("mail.smtp.port", port);
        props.setProperty("mail.smtp.timeout", "20000");
        props.setProperty("mail.smtp.connectiontimeout", "20000");
        // The improper handling of SSL and STARTLS in this area needs to be corrected.
        if (TRUE_SYMBOL_Y.equalsIgnoreCase(isSsl)) {
            props.setProperty("mail.smtp.auth", "true");
            props.setProperty("mail.smtp.ssl.enable", "true");
        } else if (TRUE_SYMBOL_Y.equalsIgnoreCase(isStartTls)) {
            props.setProperty("mail.smtp.auth", "true");
            props.setProperty("mail.smtp.starttls.enable", "true");
        }

        try {
            // Getting Sessions
            Session session = Session.getInstance(props);

            // Building Mail Information
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(email));
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(receiver));
            message.setSubject(subject);
            // Setting content
            Multipart contentPart = new MimeMultipart();
            BodyPart bodyPart = new MimeBodyPart();
            bodyPart.setContent(content, "text/html;charset=UTF-8");
            contentPart.addBodyPart(bodyPart);
            message.setContent(contentPart);

            // Connect and send
            Transport transport = session.getTransport();
            transport.connect(email, password);
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();

            System.out.println("********************** Result **********************");
            System.out.println("send success!");
            System.out.println("****************************************************");
        } catch (Exception e) {
            System.out.println("********************** Result **********************");
            System.out.println("send fail!");
            System.out.println("****************************************************");
            e.printStackTrace();
        }
    }

    private static void receive() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("Please input imap host: ");
        String host=br.readLine();
        System.out.print("Please input imap port: ");
        String port=br.readLine();
        System.out.print("Please input email address: ");
        String email =br.readLine();
        System.out.print("Please input email password: ");
        String password =br.readLine();
        System.out.print("Is SSL(y/n): ");
        String isSsl = br.readLine();

        // Building basic configuration information
        Properties props = new Properties();
        props.setProperty("mail.store.protocol", "imap");
        props.setProperty("mail.imap.host", host);
        props.setProperty("mail.imap.port", port);
        props.setProperty("mail.imap.timeout", "20000");
        props.setProperty("mail.imap.connectiontimeout", "20000");
        if (TRUE_SYMBOL_Y.equalsIgnoreCase(isSsl)) {
            props.setProperty("mail.imap.auth", "true");
            props.setProperty("mail.imap.ssl.enable", "true");
        }

        try {
            Session session = Session.getDefaultInstance(props);
            Store store = session.getStore();
            store.connect(email, password);

            Folder folder = store.getFolder("INBOX");
            if (folder.isOpen()) {
                System.out.println("The folder is opened");
            } else {
                System.out.println("Open the folder");
                folder.open(Folder.READ_ONLY);
            }

            System.out.println("********************** Result **********************");
            System.out.println("receive success!");
            System.out.println(folder.getFullName());
            System.out.println("total email count: " + folder.getMessageCount());
            System.out.println("unread email count: " + folder.getUnreadMessageCount());
            System.out.println("deleted email count: " + folder.getDeletedMessageCount());
            System.out.println("new email count: " + folder.getNewMessageCount());
            System.out.println("****************************************************");
        } catch (Exception e) {
            System.out.println("********************** Result **********************");
            System.out.println("receive fail!");
            System.out.println("****************************************************");
            e.printStackTrace();
        }
    }
}

Topics: SSL Session Java Attribute