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:
- Configure connection properties
// Here's an example of SMTP enabling SSL secure connections props.setProperty("mail.smtp.ssl.enable", "true");
- 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(); } } }