Login | ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/javautils/ViaThinkSoft Java Utils/lib/javamail-1.4.3/SSLNOTES.txt
Revision: 7
Committed: Mon Jun 14 07:55:39 2010 UTC (10 years ago) by daniel-marschall
Content type: text/plain
File size: 11642 byte(s)
Log Message:
Java Mail komplett hinzugefĆ¼gt

File Contents

# Content
1 Notes for use of SSL with JavaMail
2 ----------------------------------
3
4 JavaMail now supports accessing mail servers over connections secured
5 using SSL or TLS. To simplify such access, there are two alternative
6 approaches to enable use of SSL.
7
8 First, and perhaps the simplest, is to set a property to enable use
9 of SSL. For example, to enable use of SSL for SMTP connections, set
10 the property "mail.smtp.ssl.enable" to "true".
11
12 Alternatively, you can configure JavaMail to use one of the SSL-enabled
13 protocol names. In addition to the non-SSL JavaMail protocols "imap",
14 "pop3", and "smtp", the protocols "imaps", "pop3s", and "smtps" can
15 be used to connect to the corresponding services using an SSL
16 connection.
17
18 In addition, the "imap" and "smtp" protocols support use of the
19 STARTTLS command (see RFC 2487 and RFC 3501) to switch the connection
20 to be secured by TLS.
21
22 Use of the STARTTLS command is preferred in cases where the server
23 supports both SSL and non-SSL connections.
24
25 This SSL/TLS support in JavaMail works only when JavaMail is used on
26 a version of J2SE that includes SSL support. We have tested this
27 support on J2SE 1.4 and newer, which include SSL support. The
28 SSL support is provided by the JSSE package, which is also available
29 for earlier versions of J2SE. We have not tested such configurations.
30
31 -- STARTTLS support
32
33 The STARTTLS support is available in the standard "imap" and "smtp"
34 protocols, but must be enabled by setting the appropriate property,
35 mail.imap.starttls.enable or mail.smtp.starttls.enable, to "true".
36 When set, if the server supports the STARTTLS command, it will be
37 used after making the connection and before sending any login
38 information.
39
40
41 -- Secure protocols
42
43 When using the new protocol names, configuration properties must also use
44 these protocol names. For instance, set the property "mail.smtps.host"
45 to specify the host name of the machine to connect to when using the
46 "smtps" protocol for SMTP over SSL. Similarly, to set the IMAP protocol
47 timeout when using the "imaps" protocol for IMAP over SSL, set the property
48 "mail.imaps.timeout". See the package documentation for the different
49 protocol packages for the list of available properties, which are
50 always set using property names of the form mail.<protocol>.<property>.
51
52 The Transport.send method will use the default transport protocol,
53 which remains "smtp". To enable SMTP connections over SSL, set the
54 "mail.smtp.ssl.enable" property to "true". This is usually the easiest
55 approach.
56
57 Alternatively, to change the default transport protocol
58 returned by the Session.getTransport() method to SMTP over SSL, set
59 the property "mail.transport.protocol" to "smtps". To change the
60 transport used for internet addresses (as returned by the
61 Session.getTransport(Address) method, and used by the Transport.send
62 method), use
63
64 session.setProtocolForAddress("rfc822", "smtps");
65
66
67 -- Trusted Certificates
68
69 To establish an SSL/TLS connection, the JavaMail client must be able
70 to verify that the security certificate presented by the server
71 it is connecting to is "trusted" by the client. Trusted certificates
72 are maintained in a Java keystore file on the client. The J2SE
73 SDK "keytool" command is used to maintain the keystore file.
74
75 There are two common approaches for verifying server certificates.
76 The first approach is probably most common for servers accessible to
77 partners outside a company. The second approach is probably most
78 common for servers used within a company.
79
80 1. Server certificates may be signed be a well known public
81 Certificate Authority. The default Java keystore file contains
82 the public keys of well known Certificate Authorities and can
83 verify the server's certificate by following the chain of
84 certificates signing the server's certificate back to one of
85 these well known CA certificates.
86
87 In this case the client doesn't need to manage certificates
88 explicitly but can just use the default keystore file.
89
90 2. Server certificates may be "self-signed". In this case there is
91 no chain of signatures to use in verifying the server's certificate.
92 Instead, the client will need the server's certificate in the
93 client's keystore file. The server's certificate is imported into
94 the keystore file once, using the keytool command, and after that
95 is used to verify connections to the server. A single keystore file
96 may contain certificates of many servers.
97
98 In this case the client will need to set the appropriate System
99 properties to point to the client's keystore file containing the
100 trusted certificate. These properties can be set when invoking
101 the "java" command, or can be set programmatically. For example,
102
103 java -Djavax.net.ssl.trustStore=$HOME/.keystore ...
104
105 See the JSSE Reference Guide for details:
106 http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores
107
108
109 -- Server Identity Check
110
111 RFC 2595 specifies addition checks that must be performed on the
112 server's certificate to ensure that the server you connected to is
113 the server you intended to connect to. This reduces the risk of
114 "man in the middle" attacks. For compatibility with earlier releases
115 of JavaMail, these additional checks are disabled by default. We
116 strongly recommend that you enable these checks when using SSL. To
117 enable these checks, set the "mail.<protocol>.ssl.checkserveridentity"
118 property to "true".
119
120
121 -- Socket Factories
122
123 In earlier releases it was necessary to explicitly set a socket
124 factory property to enable use of SSL. In almost all cases, this
125 is no longer necessary. SSL support is built in. However, there
126 is one case where a special socket factory may be needed.
127
128 JavaMail now includes a special SSL socket factory that can simplify
129 dealing with servers with self-signed certificates. While the
130 recommended approach is to include the certificate in your keystore
131 as described above, the following approach may be simpler in some cases.
132
133 The class com.sun.mail.util.MailSSLSocketFactory can be used as a
134 simple socket factory that allows trusting all hosts or a specific set
135 of hosts. For example:
136
137 MailSSLSocketFactory sf = new MailSSLSocketFactory();
138 sf.setTrustAllHosts(true);
139 // or
140 // sf.setTrustedHosts(new String[] { "my-server" });
141 props.put("mail.smtp.ssl.enable", "true");
142 // also use following for additional safety
143 //props.put("mail.smtp.ssl.checkserveridentity", "true");
144 props.put("mail.smtp.ssl.socketFactory", sf);
145
146 Use of MailSSLSocketFactory avoids the need to add the certificate to
147 your keystore as described above, or configure your own TrustManager
148 as described below.
149
150
151 -- Debugging
152
153 Debugging problems with certificates and keystores can be difficult.
154 The JSSE Reference Guide contains information on debugging utilities
155 that can help. See:
156 http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#Debug
157
158 There are some debugging options in the JDK that can help, depending
159 on the sorts of problems you're having. Setting the following system
160 properties will produce additional debugging output:
161
162 java.security.debug=certpath
163 javax.net.debug=trustmanager
164
165 Set these on the command line when you run your program using, for example:
166
167 java -Djava.security.debug=certpath -Djavax.net.debug=trustmanager ...
168
169
170 -- keytool Usage
171
172 Given a certificate for the server as used in case #2 above, you can
173 import this certificate into your Java keystore file using a command
174 such as:
175
176 keytool -import -alias imap-server -file imap.cer
177
178 The keytool command can also be used to generate a self-signed certificate
179 that can be used by your mail server, if you're setting up your own server.
180 Other utilities, such as those included with the OpenSSL package, can also
181 be used to generate such certificates, and they can be imported into the
182 Java keystore using keytool.
183
184 For more information on using the keytool command, see the keytool
185 reference pages at:
186 http://java.sun.com/javase/6/docs/technotes/guides/security/index.html
187
188
189 -- Configuring Your Own Trust Manager
190
191 When using SSL/TLS, it's important to ensure that the server you connect
192 to is actually the server you expected to connect to, to prevent "man in
193 the middle" attacks on your communication. The recommended technique is
194 to configure the Java keystore using one of the methods described above.
195 If, for some reason, that approach is not workable, it's also possible
196 to configure the SSL/TLS implementation to use your own TrustManager
197 class to evaluate whether to trust the server you've connected to.
198
199 The following "dummy" classes illustrate the framework necessary to create
200 your own TrustManager implementation.
201
202 First, a replacement for the standard SSLSocketFactory is needed, to allow
203 you to specify which TrustManager to use:
204
205 ==> DummySSLSocketFactory.java <==
206
207 import java.io.IOException;
208 import java.net.InetAddress;
209 import java.net.Socket;
210
211 import javax.net.SocketFactory;
212 import javax.net.ssl.*;
213
214
215 /**
216 * DummySSLSocketFactory
217 */
218 public class DummySSLSocketFactory extends SSLSocketFactory {
219 private SSLSocketFactory factory;
220
221 public DummySSLSocketFactory() {
222 try {
223 SSLContext sslcontext = SSLContext.getInstance("TLS");
224 sslcontext.init(null,
225 new TrustManager[] { new DummyTrustManager()},
226 null);
227 factory = (SSLSocketFactory)sslcontext.getSocketFactory();
228 } catch(Exception ex) {
229 // ignore
230 }
231 }
232
233 public static SocketFactory getDefault() {
234 return new DummySSLSocketFactory();
235 }
236
237 public Socket createSocket() throws IOException {
238 return factory.createSocket();
239 }
240
241 public Socket createSocket(Socket socket, String s, int i, boolean flag)
242 throws IOException {
243 return factory.createSocket(socket, s, i, flag);
244 }
245
246 public Socket createSocket(InetAddress inaddr, int i,
247 InetAddress inaddr1, int j) throws IOException {
248 return factory.createSocket(inaddr, i, inaddr1, j);
249 }
250
251 public Socket createSocket(InetAddress inaddr, int i)
252 throws IOException {
253 return factory.createSocket(inaddr, i);
254 }
255
256 public Socket createSocket(String s, int i, InetAddress inaddr, int j)
257 throws IOException {
258 return factory.createSocket(s, i, inaddr, j);
259 }
260
261 public Socket createSocket(String s, int i) throws IOException {
262 return factory.createSocket(s, i);
263 }
264
265 public String[] getDefaultCipherSuites() {
266 return factory.getDefaultCipherSuites();
267 }
268
269 public String[] getSupportedCipherSuites() {
270 return factory.getSupportedCipherSuites();
271 }
272 }
273
274
275 Next you need the actual implementation of the TrustManager. This dummy
276 trust manager trusts anything. THIS IS NOT SECURE!!!
277
278 ==> DummyTrustManager.java <==
279
280 import javax.net.ssl.X509TrustManager;
281 import java.security.cert.X509Certificate;
282
283
284 /**
285 * DummyTrustManager - NOT SECURE
286 */
287 public class DummyTrustManager implements X509TrustManager {
288
289 public void checkClientTrusted(X509Certificate[] cert, String authType) {
290 // everything is trusted
291 }
292
293 public void checkServerTrusted(X509Certificate[] cert, String authType) {
294 // everything is trusted
295 }
296
297 public X509Certificate[] getAcceptedIssuers() {
298 return new X509Certificate[0];
299 }
300 }
301
302 Finally, you need to configure JavaMail to use your SSLSocketFactory.
303 Set the appropriate protocol-specific property, e.g.,
304
305 props.setProperty("mail.imap.ssl.enable", "true");
306 props.setProperty("mail.imap.ssl.socketFactory.class",
307 "DummySSLSocketFactory");
308 props.setProperty("mail.imap.ssl.socketFactory.fallback", "false");
309 Session session = Session.getInstance(props, null);
310
311 Similar properties would need to be set to use other protocols.