使用jtds-1.3.1.jar连接Android应用到Azure SQL遇TLS版本错误
问题:Azure SQL连接提示客户端TLS版本低于服务器要求
E/SQL Exception:: Reason: Login failed due to client TLS version being less than minimal TLS version allowed by the server.
试过所有和TLS版本相关的解决方案,还是无法解决,始终抛出上述错误。
已尝试操作
- 先后将Azure SQL服务器的最低TLS版本配置为1.0、1.1、1.2
- 使用jtds-1.3.1.jar驱动
- 使用mssql-jdbc-12.2.0.jre8.jar驱动
- 可通过Microsoft SSMS正常连接服务器
- 在SSMS中成功执行测试查询:
USE userdata;\nSELECT * FROM user;
相关代码
CheckLogin异步任务类
public class CheckLogin extends AsyncTask<String,String,String>{ @Override protected String doInBackground(String... params){ con = sqlserverconn(); // 连接userdata数据库 String query = "USE userdata;\n" + "SELECT * FROM user;"; try { // 初始化SSLContext sc = SSLContext.getInstance("TLSv1.2"); sc.init(null, null, null); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); Statement statement = con.createStatement(); // 创建Statement ResultSet result = statement.executeQuery(query); // 执行查询 // 获取查询返回的数据 if(result.next()){ id = result.getInt("Id"); deviceid = result.getString("deviceId"); username = result.getString("userName"); password = result.getString("password"); email = result.getString("email"); // 更新UI runOnUiThread(new Runnable() { @Override public void run() { login_id.setText(String.valueOf(id)); login_deviceid.setText(deviceid); login_username.setText(username); login_password.setText(password); login_email.setText(email); } }); } result.close(); statement.close(); con.close(); } catch (SQLException e) { Log.e("SQL Exception: ",e.getMessage()); throw new RuntimeException(e); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (KeyManagementException e) { throw new RuntimeException(e); } return ""; } }
数据库连接方法
@SuppressLint("newApi") public Connection sqlserverconn(){ StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); Connection connection = null; String ConnectionURL = null; try { Class.forName("net.sourceforge.jtds.jdbc.Driver"); // 数据库连接字符串 ConnectionURL = "jdbc:jtds:sqlserver://userdata-dataserver.database.windows.net:1433;DatabaseName=userdata;user=userdata@userdata-dataserver;password=xxxxxxx;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;"; connection =DriverManager.getConnection(ConnectionURL); } catch (SQLException e) { Log.e("SQL Exception: ",e.getMessage()); } catch (ClassNotFoundException e) { Log.e("Class Not Found: ",e.getMessage()); throw new RuntimeException(e); } return connection; }
解决思路
1. 修复jtds驱动的TLS配置
jtds-1.3.1默认不会强制使用TLS1.2,需要在连接字符串中显式指定SSL协议版本,修改后的连接字符串如下:
jdbc:jtds:sqlserver://userdata-dataserver.database.windows.net:1433;DatabaseName=userdata;user=userdata@userdata-dataserver;password=xxxxxxx;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;sslProtocol=TLSv1.2;
2. 改用mssql-jdbc驱动并正确配置
如果切换到微软官方的mssql-jdbc驱动,需要修改驱动类和连接字符串:
@SuppressLint("newApi") public Connection sqlserverconn(){ StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); Connection connection = null; String ConnectionURL = null; try { // 替换为微软官方驱动类 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); // 调整为官方连接字符串格式并指定TLS版本 ConnectionURL = "jdbc:sqlserver://userdata-dataserver.database.windows.net:1433;databaseName=userdata;user=userdata@userdata-dataserver;password=xxxxxxx;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;sslProtocol=TLSv1.2"; connection =DriverManager.getConnection(ConnectionURL); } catch (SQLException e) { Log.e("SQL Exception: ",e.getMessage()); } catch (ClassNotFoundException e) { Log.e("Class Not Found: ",e.getMessage()); throw new RuntimeException(e); } return connection; }
3. 注意Android系统版本的TLS支持
如果设备Android版本低于5.0(API 21),系统默认不支持TLS1.2,此时需要为JDBC驱动自定义SSLSocketFactory来强制启用TLS1.2,你代码中设置HttpsURLConnection的SSLSocketFactory对JDBC连接无效。
4. 确认Azure SQL服务器配置生效
修改Azure SQL的最低TLS版本后,可能需要等待5-10分钟才能完全生效,建议在Azure门户中再次确认服务器的TLS配置是否正确。
内容的提问来源于stack exchange,提问作者LuciferRules
相关产品推荐
相关产品推荐

