javamail

简介:
http://www.oracle.com/technetwork/java/javamail/javamail147sslnotes-1917783.html

		Notes for use of SSL with JavaMail
		----------------------------------

JavaMail now supports accessing mail servers over connections secured
using SSL or TLS.  To simplify such access, there are two alternative
approaches to enable use of SSL.

First, and perhaps the simplest, is to set a property to enable use
of SSL.  For example, to enable use of SSL for SMTP connections, set
the property "mail.smtp.ssl.enable" to "true".

Alternatively, you can configure JavaMail to use one of the SSL-enabled
protocol names.  In addition to the non-SSL JavaMail protocols "imap",
"pop3", and "smtp", the protocols "imaps", "pop3s", and "smtps" can
be used to connect to the corresponding services using an SSL
connection.

In addition, the "imap" and "smtp" protocols support use of the
STARTTLS command (see RFC 2487 and RFC 3501) to switch the connection
to be secured by TLS.

Use of the STARTTLS command is preferred in cases where the server
supports both SSL and non-SSL connections.

This SSL/TLS support in JavaMail works only when JavaMail is used on
a version of J2SE that includes SSL support.  We have tested this
support on J2SE 1.4 and newer, which include SSL support.  The
SSL support is provided by the JSSE package, which is also available
for earlier versions of J2SE.  We have not tested such configurations.

-- STARTTLS support

The STARTTLS support is available in the standard "imap" and "smtp"
protocols, but must be enabled by setting the appropriate property,
mail.imap.starttls.enable or mail.smtp.starttls.enable, to "true".
When set, if the server supports the STARTTLS command, it will be
used after making the connection and before sending any login
information.


-- Secure protocols

When using the new protocol names, configuration properties must also use
these protocol names.  For instance, set the property "mail.smtps.host"
to specify the host name of the machine to connect to when using the
"smtps" protocol for SMTP over SSL.  Similarly, to set the IMAP protocol
timeout when using the "imaps" protocol for IMAP over SSL, set the property
"mail.imaps.timeout".  See the package documentation for the different
protocol packages for the list of available properties, which are
always set using property names of the form mail.<protocol>.<property>.

The Transport.send method will use the default transport protocol,
which remains "smtp".  To enable SMTP connections over SSL, set the
"mail.smtp.ssl.enable" property to "true".  This is usually the easiest
approach.

Alternatively, to change the default transport protocol 
returned by the Session.getTransport() method to SMTP over SSL, set
the property "mail.transport.protocol" to "smtps".  To change the
transport used for internet addresses (as returned by the
Session.getTransport(Address) method, and used by the Transport.send
method), use

	session.setProtocolForAddress("rfc822", "smtps");


-- Trusted Certificates

To establish an SSL/TLS connection, the JavaMail client must be able
to verify that the security certificate presented by the server
it is connecting to is "trusted" by the client.  Trusted certificates
are maintained in a Java keystore file on the client.  The J2SE
SDK "keytool" command is used to maintain the keystore file.

There are two common approaches for verifying server certificates.
The first approach is probably most common for servers accessible to
partners outside a company.  The second approach is probably most
common for servers used within a company.

1. Server certificates may be signed be a well known public
   Certificate Authority.  The default Java keystore file contains
   the public keys of well known Certificate Authorities and can
   verify the server's certificate by following the chain of
   certificates signing the server's certificate back to one of
   these well known CA certificates.

   In this case the client doesn't need to manage certificates
   explicitly but can just use the default keystore file.

2. Server certificates may be "self-signed".  In this case there is
   no chain of signatures to use in verifying the server's certificate.
   Instead, the client will need the server's certificate in the
   client's keystore file.  The server's certificate is imported into
   the keystore file once, using the keytool command, and after that
   is used to verify connections to the server.  A single keystore file
   may contain certificates of many servers.

   In this case the client will need to set the appropriate System
   properties to point to the client's keystore file containing the
   trusted certificate.  These properties can be set when invoking
   the "java" command, or can be set programmatically.  For example,

	java -Djavax.net.ssl.trustStore=$HOME/.keystore ...

   See the JSSE Reference Guide for details:
   http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores


-- Server Identity Check

RFC 2595 specifies addition checks that must be performed on the
server's certificate to ensure that the server you connected to is
the server you intended to connect to.  This reduces the risk of
"man in the middle" attacks.  For compatibility with earlier releases
of JavaMail, these additional checks are disabled by default.  We
strongly recommend that you enable these checks when using SSL.  To
enable these checks, set the "mail.<protocol>.ssl.checkserveridentity"
property to "true".


-- Socket Factories

In earlier releases it was necessary to explicitly set a socket
factory property to enable use of SSL.  In almost all cases, this
is no longer necessary.  SSL support is built in.  However, there
is one case where a special socket factory may be needed.

JavaMail now includes a special SSL socket factory that can simplify
dealing with servers with self-signed certificates.  While the
recommended approach is to include the certificate in your keystore
as described above, the following approach may be simpler in some cases.

The class com.sun.mail.util.MailSSLSocketFactory can be used as a
simple socket factory that allows trusting all hosts or a specific set
of hosts.  For example:

	MailSSLSocketFactory sf = new MailSSLSocketFactory();
	sf.setTrustAllHosts(true);
	// or
	// sf.setTrustedHosts(new String[] { "my-server" });
	props.put("mail.smtp.ssl.enable", "true");
	// also use following for additional safety
	//props.put("mail.smtp.ssl.checkserveridentity", "true");
	props.put("mail.smtp.ssl.socketFactory", sf);

Use of MailSSLSocketFactory avoids the need to add the certificate to
your keystore as described above, or configure your own TrustManager
as described below.


-- Debugging

Debugging problems with certificates and keystores can be difficult.
The JSSE Reference Guide contains information on debugging utilities
that can help.  See:
http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#Debug

There are some debugging options in the JDK that can help, depending
on the sorts of problems you're having.  Setting the following system
properties will produce additional debugging output:

	java.security.debug=certpath
	javax.net.debug=trustmanager 

Set these on the command line when you run your program using, for example:

	java -Djava.security.debug=certpath -Djavax.net.debug=trustmanager ...


-- keytool Usage

Given a certificate for the server as used in case #2 above, you can
import this certificate into your Java keystore file using a command
such as:

	keytool -import -alias imap-server -file imap.cer

The keytool command can also be used to generate a self-signed certificate
that can be used by your mail server, if you're setting up your own server.
Other utilities, such as those included with the OpenSSL package, can also
be used to generate such certificates, and they can be imported into the
Java keystore using keytool.

For more information on using the keytool command, see the keytool
reference pages at:
http://download.oracle.com/javase/6/docs/technotes/guides/security/index.html


-- Configuring Your Own Trust Manager

When using SSL/TLS, it's important to ensure that the server you connect
to is actually the server you expected to connect to, to prevent "man in
the middle" attacks on your communication.  The recommended technique is
to configure the Java keystore using one of the methods described above.
If, for some reason, that approach is not workable, it's also possible
to configure the SSL/TLS implementation to use your own TrustManager
class to evaluate whether to trust the server you've connected to.

The following "dummy" classes illustrate the framework necessary to create
your own TrustManager implementation.

First, a replacement for the standard SSLSocketFactory is needed, to allow
you to specify which TrustManager to use:

==> DummySSLSocketFactory.java <==

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

import javax.net.SocketFactory;
import javax.net.ssl.*;


/**
 * DummySSLSocketFactory
 */
public class DummySSLSocketFactory extends SSLSocketFactory {
    private SSLSocketFactory factory;

    public DummySSLSocketFactory() {
	try {
	    SSLContext sslcontext = SSLContext.getInstance("TLS");
	    sslcontext.init(null,
				 new TrustManager[] { new DummyTrustManager()},
				 null);
	    factory = (SSLSocketFactory)sslcontext.getSocketFactory();
	} catch(Exception ex) {
	    // ignore
	}
    }

    public static SocketFactory getDefault() {
	return new DummySSLSocketFactory();
    }

    public Socket createSocket() throws IOException {
	return factory.createSocket();
    }

    public Socket createSocket(Socket socket, String s, int i, boolean flag)
				throws IOException {
	return factory.createSocket(socket, s, i, flag);
    }

    public Socket createSocket(InetAddress inaddr, int i,
				InetAddress inaddr1, int j) throws IOException {
	return factory.createSocket(inaddr, i, inaddr1, j);
    }

    public Socket createSocket(InetAddress inaddr, int i)
				throws IOException {
	return factory.createSocket(inaddr, i);
    }

    public Socket createSocket(String s, int i, InetAddress inaddr, int j)
				throws IOException {
	return factory.createSocket(s, i, inaddr, j);
    }

    public Socket createSocket(String s, int i) throws IOException {
	return factory.createSocket(s, i);
    }

    public String[] getDefaultCipherSuites() {
	return factory.getDefaultCipherSuites();
    }

    public String[] getSupportedCipherSuites() {
	return factory.getSupportedCipherSuites();
    }
}


Next you need the actual implementation of the TrustManager.  This dummy
trust manager trusts anything.  THIS IS NOT SECURE!!!

==> DummyTrustManager.java <==

import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;


/**
 * DummyTrustManager - NOT SECURE
 */
public class DummyTrustManager implements X509TrustManager {

    public void checkClientTrusted(X509Certificate[] cert, String authType) {
	// everything is trusted
    }

    public void checkServerTrusted(X509Certificate[] cert, String authType) {
	// everything is trusted
    }

    public X509Certificate[] getAcceptedIssuers() {
	return new X509Certificate[0];
    }
}

Finally, you need to configure JavaMail to use your SSLSocketFactory.
Set the appropriate protocol-specific property, e.g.,

    props.setProperty("mail.imap.ssl.enable", "true");
    props.setProperty("mail.imap.ssl.socketFactory.class",
					"DummySSLSocketFactory");
    props.setProperty("mail.imap.ssl.socketFactory.fallback", "false");
    Session session = Session.getInstance(props, null);

Similar properties would need to be set to use other protocols.
相关文章
|
定位技术
阿里组织架构升级中的“中台”到底是什么
阿里巴巴在2015年12月进行组织升级,就是“大中台,小前台”的模式。主要的思路是打破原来树状结构,小前台距离一线更近,业务全能,这样便于快速决策、敏捷行动;支持类的业务放在中台,扮演平台支撑的角色。
12388 0
|
机器学习/深度学习 自然语言处理 并行计算
多模态大模型技术原理与实战(2)
大模型被广泛应用有以下几个前提:效果好、效率高、成本可控,目前,大模型在这几个方面还不够理想。
933 5
|
Ubuntu Unix Linux
Linux专栏01:Linux发展历史及背景介绍
Linux专栏01:Linux发展历史及背景介绍
1218 0
|
前端开发 JavaScript 定位技术
高德客户端及引擎技术架构演进与思考
高德客户端及引擎技术架构演进与思考
|
编解码 图形学 开发者
【unity小技巧】使用三种方式实现瞄准瞄具放大变焦效果
【unity小技巧】使用三种方式实现瞄准瞄具放大变焦效果
1387 0
|
监控 网络协议 Java
Java中的WebSocket应用与实践
Java中的WebSocket应用与实践
|
机器学习/深度学习 算法 测试技术
如何应对缺失值带来的分布变化?探索填充缺失值的最佳插补算法
该文探讨了缺失值插补的不同方法,比较了它们恢复数据真实分布的效果。文章指出,处理插补尤其在小样本或复杂数据时是个挑战,需要选择能适应数据分布变化的方法。文中介绍了完全随机缺失(MCAR)、随机缺失(MAR)和非随机缺失(MNAR)三种机制,并以一个简单的例子展示了数据分布变化。文章通过比较均值插补、回归插补和高斯插补,强调了高斯插补在重现数据分布方面更优。评估插补方法时,不应仅依赖于RMSE,而应关注分布预测,使用如能量距离这样的指标。此外,即使在随机缺失情况下,数据分布也可能因模式变化而变化,需要考虑适应这些变化的插补方法。
911 2
|
安全 算法 数据库
由古论今,三千年加密算法发展史
作为一种安全手段,加密算法和我们大多数人的生活发生着紧密联系。只要你上网,都会从中受益,因为凡是使用https的网站都已经使用了加密协议TLS/SSL。因此,我们都在被动享受加密算法带来的隐私保护及通讯安全。
3248 0

热门文章

最新文章