Java代码SSL https 加密连接 sqlserver
3种连接sqlserver方式 URL 的区别:
1)jdbc:sqlserver://IP:port;DatabaseName=dbName;autoReconnectForPools=true;
2)jdbc:sqlserver://IP:port;DatabaseName=dbName;autoReconnectForPools=true;encrypt=true;trustServerCertificate=true;
3)jdbc:sqlserver://IP:port;DatabaseName=dbName;autoReconnectForPools=true;encrypt=true;trustServerCertificate=false;trustStore=/path/to/truststore.ks;trustStorePassword=12345678;hostNameInCertificate=cer证书里的域名
接下来我们说说这3种连接方式的区别:
一、非加密形式的通用连接方式
jdbc:sqlserver://IP:port;DatabaseName=GatewayV7QA;autoReconnectForPools=true;
二、无条件信任任何根证书的连接方式
jdbc:sqlserver://IP:port;DatabaseName=GatewayV7QA;autoReconnectForPools=true;encrypt=true;trustServerCertificate=true;
trustServerCertificate=true; 这个参数 true 表示无条件信任server端返回的任何根证书
三、客户端需验证server端SSL证书的连接方式
sqlserver官方文档地址——如何配置SSL url:
sqlserver官方文档地址——如何生成 ks 证书:
为了避开我踏过的坑,还是按照我的连接方案往下看吧。首先加上sqlserver的驱动:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.2.1.jre8</version>
<scope>test</scope>
</dependency>
然后url 连接:
jdbc:sqlserver://IP:port;DatabaseName=dbName;autoReconnectForPools=true;encrypt=true;trustServerCertificate=false;trustStore=/path/to/truststore.ks;trustStorePassword=12345678;hostNameInCertificate=cer证书里的域名
这里把 trustServerCertificate=false 设置为false,表示不再随意信任任何server端的根证书了,所以我们需要拿server端的 cer 证书生成客户端的 ks 证书。
【根据cer证书生成JKS证书】
第一步:生成新的JKS证书,保证Keystore type: jks,要不然会有连接问题。
keytool -genkey -alias Certificate -keyalg RSA -keysize 2048 -keystore truststore.ks -deststoretype jks // 指定证书格式为jks
第二步:压入三个cer证书文件:
打开cmd窗口,进入 serverXXX.cer 所在路径,执行Java的 keytool 命令生成我们需要的 truststore.ks 证书 :
keytool -import -v -trustcacerts -alias aliasNameA -file domainA.cer -keystore truststore.ks
keytool -import -v -trustcacerts -alias aliasNameB -file domainB.cer -keystore truststore.ks //把第二个cer证书压缩到同一个ks文件里
keytool -import -v -trustcacerts -alias aliasNameC -file domainC.cer -keystore truststore.ks //把第三个cer证书压缩到同一个ks文件里
第三步:验证ks证书里面的keystore type格式是否为jks
首先验证是JKS格式证书,其中Keystore type: JKS才行,命令行验证: keytool -list -rfc -keystore path/truststore.ks
keytool 命令之后会生成 ks 证书,然后配置正确的ks 证书路径 trustStore=/path/to/truststore.ks
truststore.ks 证书生成过程中,有两个步骤需要手工输入:
Enter keystore password: 12345678 // 这里输入的密码就是url连接里的密码:trustStorePassword=12345678
Trust this certificate? [no]: yes
truststore.ks 证书生成过程中,会显示该 cer 证书包含的信任的server端域名,hostNameInCertificate 这个参数必须配置成这些域名中的一个:
SubjectAlternativeName [
DNSName: domainA.com
DNSName: domainB.com
DNSName: domainC.com // 这里的ABC domain分别对应上面的server ABC.cer证书,所以这个jks证书就能SSL加密访问三个server了
]
第四步:Java代码验证SSL连接:
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SSL_sqlserver_trustServerCertificate_false_Test {
static String SSL_URL = "jdbc:sqlserver://IP:port;DatabaseName=dbName;" +
"autoReconnectForPools=true;ApplicationIntent=ReadOnly;encrypt=true;trustServerCertificate=false;" +
"trustStore=/path/to/truststore.ks;" + // 用server端的cer证书生成的ks证书
"trustStorePassword=12345678;" + // truststore.ks 证书生成时的密码
"hostNameInCertificate=domain1.com"
;
static String USERNAME = "username";
static String PASSWORD = "password";
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection(SSL_URL, USERNAME, PASSWORD);
ResultSet resultSet = conn.createStatement().executeQuery("select 100, 'trustServerCertificate=false' ");
while(resultSet.next()){
int queryInt = resultSet.getInt(1);
String getString = resultSet.getString(2);
System.out.println("queryInt==="+queryInt);
System.out.println("getString::: "+getString);
}
conn.close();
}
}
如果连接成功,控制台打印:
queryInt===100
getString::: trustServerCertificate=false
四、报错解决思路
4.1、InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
如果是这个错误,表示ks证书路径不对或者ks证书无效,也就是 trustStore=/path/to/truststore.ks 这个值设置错了
4.2、no sqljdbc_auth in java.library.path 或者 sqljdbc_auth.dll: unknown file type, first eight bytes: 0x4D 0x5A 0x90 0x00 0x03 0x00 0x00 0x00
这种找 dll 错误的貌似都是发生在windows端的错误,但是我这里证明了是因为连 trustStore、trustStorePassword、hostNameInCertificate 这3个参数都没配置所以才会报错
4.3、SQLServerException: This driver is not configured for integrated authentication
trustStore、trustStorePassword、hostNameInCertificate 这3个参数都没配置所以才会报错