Android应用中HTTPS动态Basic Auth实现及SSL握手异常解决方案
Android HTTPS动态Basic Auth实现及SSL握手异常解决方案
我来分享一下Android应用中基于HTTPS的动态Basic Auth实现方案,同时解决大家常遇到的javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found异常问题。你可以直接修改代码里的URL、用户名和密码来适配自己的业务场景。
一、动态Basic Auth实现思路
动态Basic Auth的核心是在HTTPS请求的Header中添加Authorization字段,值为Basic + Base64编码的"用户名:密码"。我们通过异步任务执行网络请求,避免阻塞主线程影响UI体验。
二、SSL握手异常解决方案
针对Trust anchor for certification path not found这个异常,核心原因是设备默认不信任服务器的SSL证书,这里提供两种常用解决方案:
- 方案1:信任所有证书(仅测试环境可用):实现自定义SSLSocketFactory跳过证书验证,注意生产环境绝对不能用这种方式,会带来严重安全风险。
- 方案2:导入服务器证书到应用(生产环境推荐):将服务器的CA证书打包到应用
res/raw目录,创建自定义TrustManager来信任该证书,保证请求安全性。
三、完整代码示例
以下是MainActivity.java的完整代码,包含动态Basic Auth实现和SSL异常处理(示例用信任所有证书的方式,仅适用于测试):
import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Base64; import android.view.View; import android.widget.Toast; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.security.cert.X509Certificate; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public class MainActivity extends AppCompatActivity { // 替换为你的目标URL、用户名、密码 private static final String TARGET_URL = "https://your-target-url.com/api"; private static final String USERNAME = "your-username"; private static final String PASSWORD = "your-password"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // 点击触发请求的方法,可绑定到按钮点击事件 public void sendHttpsAuthRequest(View view) { new HttpsAuthAsyncTask().execute(); } private class HttpsAuthAsyncTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... voids) { String responseResult = ""; try { // 处理SSL证书信任问题(测试环境用) TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) {} @Override public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); // 创建HTTPS连接 URL url = new URL(TARGET_URL); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); // 构造Basic Auth请求头 String credentials = USERNAME + ":" + PASSWORD; String authHeader = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); connection.setRequestProperty("Authorization", authHeader); // 设置请求方法(根据需求改成POST等) connection.setRequestMethod("GET"); // 读取响应内容 InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder stringBuilder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { stringBuilder.append(line); } responseResult = stringBuilder.toString(); // 关闭资源 reader.close(); inputStream.close(); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); responseResult = "请求失败:" + e.getMessage(); } return responseResult; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); // 将结果展示到UI上,这里用Toast示例 Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show(); } } }
额外注意事项
- 记得在
AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 测试环境用信任所有证书的方式即可,但生产环境一定要用导入合法证书的方案,避免安全漏洞
- 异步任务也可以用Coroutine、OkHttp等更现代的方式替代,AsyncTask只是示例实现
内容的提问来源于stack exchange,提问作者Deepesh Ahuja
相关产品推荐
相关产品推荐

