要想使SSL支持能够工作,必须满足下述要求:
· 包含JSSE(Java安全套接字扩展)的JDK,如JDK-1.4.1或更高版本。SSL目前不能与能够为其添加JSSE的JDK一起工作,如JDK-1.2.x或JDK-1.3.x,原因在于下述JSSE缺陷:http://developer.java.sun.com/developer/bugParade/bugs/4273544.html
· 支持SSL并已编译和配置了该功能的MySQL服务器,如MySQL-4.0.4和更高版本,请参见:http://www.mysql.com/doc/en/Secure_connections.html
· 客户端证书(在本节稍后介绍)。
首先,需要将MySQL服务器CA证书导入到Java truststore。在MySQL源码分发版的“SSL”子目录下给出了1个示例MySQL服务器CA证书。SSL将使用它来确定是否与安全MySQL服务器进行通信。
要想使用Java的“keytool”在当前目录下创建truststore,并导入服务器的CA证书(“cacert.pem”),可采取下述方式(假定“keytool”位于路径中。它位于JDK或JRE的“bin”子目录下):
shell> keytool -import -alias mysqlServerCACert -file cacert.pem -keystore truststore
Keytool将给出下述响应信息:
Enter keystore password: ********* Owner: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Some -State, C=RU Issuer: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Som e-State, C=RU Serial number: 0 Valid from: Fri Aug 02 16:55:53 CDT 2002 until: Sat Aug 02 16:55:53 CDT 2003 Certificate fingerprints: MD5: 61:91:A0:F2:03:07:61:7A:81:38:66:DA:19:C4:8D:AB SHA1: 25:77:41:05:D5:AD:99:8C:14:8C:CA:68:9C:2F:B8:89:C3:34:4D:6C Trust this certificate? [no]: yes Certificate was added to keystore
随后,需要生成客户端证书,以便MySQL服务器知道它正与安全客户端进行通信:
shell> keytool -genkey -keyalg rsa -alias mysqlClientCertificate -keystore keystore
Keytool将给出下述提示信息,并在当目录下创建名为“keystore”的密钥存储器。
你应使用与具体情况相适应的新作出响应:
Enter keystore password: ********* What is your first and last name? [Unknown]: Matthews What is the name of your organizational unit? [Unknown]: Software Development What is the name of your organization? [Unknown]: MySQL AB What is the name of your City or Locality? [Unknown]: Flossmoor What is the name of your State or Province? [Unknown]: IL What is the two-letter country code for this unit? [Unknown]: US Is <CN=Matthews, OU=Software Development, O=MySQL AB, L=Flossmoor, ST=IL, C=US> correct? [no]: y 输入<mysqlClientCertificate>的密码 如果与keystore的密码相同,按回车):
最后,要想使JSSE能够使用你生成的keystore和truststore,启动JVM时,需要设置下述系统属性,用你所创建的keystore文件完整路径替换“path_to_keystore_file”,用你所创建的truststore文件完整路径替换“path_to_truststore_file”,并为每个属性使用恰当的密码值。
-Djavax.net.ssl.keyStore=path_to_keystore_file -Djavax.net.ssl.keyStorePassword=********* -Djavax.net.ssl.trustStore=path_to_truststore_file -Djavax.net.ssl.trustStorePassword=*********
此外,还需要在用于MySQL Connector/J的连接参数中将“useSSL”设置为“真”,方法是,在URL中添加“useSSL=true”,或在准备传递给DriverManager.getConnection()的java.util.Properties实例中将“useSSL”设置为“真”。
你可以打开JSSE调试功能能够,测试SSL是否工作(详情如下),并查找下述关键事件:
... *** ClientHello, v3.1 RandomCookie: GMT: 1018531834 bytes = { 199, 148, 180, 215, 74, 12, 54, 244, 0, 168, 55, 103, 215, 64, 16, 138, 225, 190, 132, 153, 2, 217, 219, 239, 202, 19, 121, 78 } Session ID: {} Cipher Suites: { 0, 5, 0, 4, 0, 9, 0, 10, 0, 18, 0, 19, 0, 3, 0, 17 } Compression Methods: { 0 } *** [write] MD5 and SHA1 hashes: len = 59 0000: 01 00 00 37 03 01 3D B6 90 FA C7 94 B4 D7 4A 0C ...7..=.......J. 0010: 36 F4 00 A8 37 67 D7 40 10 8A E1 BE 84 99 02 D9 6...7g.@........ 0020: DB EF CA 13 79 4E 00 00 10 00 05 00 04 00 09 00 ....yN.......... 0030: 0A 00 12 00 13 00 03 00 11 01 00 ........... main, WRITE: SSL v3.1 Handshake, length = 59 main, READ: SSL v3.1 Handshake, length = 74 *** ServerHello, v3.1 RandomCookie: GMT: 1018577560 bytes = { 116, 50, 4, 103, 25, 100, 58, 202, 79, 185, 178, 100, 215, 66, 254, 21, 83, 187, 190, 42, 170, 3, 132, 110, 82, 148, 160, 92 } Session ID: {163, 227, 84, 53, 81, 127, 252, 254, 178, 179, 68, 63, 182, 158, 30, 11, 150, 79, 170, 76, 255, 92, 15, 226, 24, 17, 177, 219, 158, 177, 187, 143} Cipher Suite: { 0, 5 } Compression Method: 0 *** %% Created: [Session-1, SSL_RSA_WITH_RC4_128_SHA] ** SSL_RSA_WITH_RC4_128_SHA [read] MD5 and SHA1 hashes: len = 74 0000: 02 00 00 46 03 01 3D B6 43 98 74 32 04 67 19 64 ...F..=.C.t2.g.d 0010: 3A CA 4F B9 B2 64 D7 42 FE 15 53 BB BE 2A AA 03 :.O..d.B..S..*.. 0020: 84 6E 52 94 A0 5C 20 A3 E3 54 35 51 7F FC FE B2 .nR..\ ..T5Q.... 0030: B3 44 3F B6 9E 1E 0B 96 4F AA 4C FF 5C 0F E2 18 .D?.....O.L.\... 0040: 11 B1 DB 9E B1 BB 8F 00 05 00 .......... main, READ: SSL v3.1 Handshake, length = 1712 ...
设置了下述系统属性时,JSSE可提供调试功能(为STDOUT):-Djavax.net.debug=all。它用于设定要使用的keystores和truststores,以及在SSL握手和证书交换过程中将出现什么。当你尝试进行SSL连接时,如果打算确定不能工作的部分,该设置十分有用。