信任锚不仅在设备上找到,而且在模拟器上运行?
Posted
技术标签:
【中文标题】信任锚不仅在设备上找到,而且在模拟器上运行?【英文标题】:Trust anchors not found only on device but running on emulator? 【发布时间】:2017-10-03 06:52:38 【问题描述】:一切都在标题中,我不明白为什么我的代码在模拟器中有效,但在我的设备上无效。它抛出“未找到信任锚异常”!怎么可能?我尝试了关于 trustManager 的 okhttp.builder 的实现,但仍然......请帮助!!
这是我的课:
public abstract class NewsFragment extends Fragment
private static final String TAAG = NewsFragment.class.getSimpleName();
protected ItemAdapter mArticleAdapter;
protected RecyclerView mRecyclerView;
protected NewsFragment.OnNewSelectedInterface mListener;
protected ItemAdapter.OnNewsInsertedInterface mListener2;
protected RecyclerView.LayoutManager mManager;
protected SwipeRefreshLayout mSwipeRefreshLayout;
public static final String KEY_LIST = "key_list";
public interface OnNewSelectedInterface
void onListNewSelected(int index, ArrayList<Article> articles);
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.list_present_news, container, false);
mListener = (NewsFragment.OnNewSelectedInterface) getActivity();
mListener2 = (ItemAdapter.OnNewsInsertedInterface) getActivity();
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeContainer);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
mManager = new LinearLayoutManager(getActivity());
mArticleAdapter = new ItemAdapter(getActivity(), new ArrayList<>(), mListener, mListener2);
if (!isNetworkAvailable()) alertUserAboutError();
mRecyclerView.setAdapter(mArticleAdapter);
mRecyclerView.setLayoutManager(mManager);
mSwipeRefreshLayout.setRefreshing(true);
new Downloader().execute(getUrl());
//new Downloader().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getUrl());
refreshData();
setDividerRecyclerView();
return view;
private void setDividerRecyclerView()
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView
.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
private void alertUserAboutError()
AlertDialogFragment alertDialogFragment = new AlertDialogFragment();
alertDialogFragment.show(getActivity().getFragmentManager(), "error_dialog");
protected abstract String[] getUrl();
private boolean isNetworkAvailable()
ConnectivityManager manager = (ConnectivityManager)
getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected())
isAvailable = true;
return isAvailable;
private void refreshData()
mSwipeRefreshLayout.setOnRefreshListener(() ->
mArticleAdapter.clear();
new Downloader().execute(getUrl());
);
mSwipeRefreshLayout.setColorSchemeResources(
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
private class Downloader extends AsyncTask<String, Void, ArrayList<Article>>
ArrayList<Article> mArticleArrayList = new ArrayList<>();
OkHttpClient mClient = new OkHttpClient();
@Override
protected ArrayList<Article> doInBackground(String... strings)
for (String aMUrl : getUrl())
Request mRequest = new Request.Builder().url(aMUrl).build();
try
Response response = mClient.newCall(mRequest).execute();
try
if (response.isSuccessful())
String json = response.body().string();
mArticleArrayList = getMultipleUrls(json);
catch (IOException | JSONException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
return mArticleArrayList;
@Override
protected void onPostExecute(ArrayList<Article> articles)
mArticleAdapter.addAll(articles);
mSwipeRefreshLayout.setRefreshing(false);
Log.v(TAAG, String.valueOf(mArticleAdapter.getItemCount()));
private ArrayList<Article> getMultipleUrls(String jsonData) throws JSONException
if (mArticleArrayList == null || mArticleArrayList.size() == 0)
mArticleArrayList = getArticleForecast(jsonData);
else
mArticleArrayList.addAll(getArticleForecast(jsonData));
return mArticleArrayList;
private ArrayList<Article> getArticleForecast(String jsonData) throws JSONException
JSONObject forecast = new JSONObject(jsonData);
JSONArray articles = forecast.getJSONArray("articles");
ArrayList<Article> listArticles = new ArrayList<>(articles.length());
for (int i = 0; i < articles.length(); i++)
JSONObject jsonArticle = articles.getJSONObject(i);
Article article = new Article();
String urlImage = jsonArticle.getString("urlToImage");
article.setTitle(jsonArticle.getString("title"));
article.setDescription(jsonArticle.getString("description"));
article.setImageView(urlImage);
article.setArticleUrl(jsonArticle.getString("url"));
article.setUrlToImage(jsonArticle.getString("urlToImage"));
listArticles.add(i, article);
return listArticles;
这是日志:
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:306)
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:242)
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:200)
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.connection.RealConnection.buildConnection(RealConnection.java:174)
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:114)
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:196)
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:132)
05-04 23:39:01.382 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:101)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at okhttp3.RealCall.execute(RealCall.java:63)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at com.silho.ideo.knewsproject.Fragments.PresentNews.NewsFragment$Downloader.doInBackground(NewsFragment.java:170)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at com.silho.ideo.knewsproject.Fragments.PresentNews.NewsFragment$Downloader.doInBackground(NewsFragment.java:143)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-04 23:39:01.383 9856-9997/com.silho.ideo.knewsproject W/System.err: at java.lang.Thread.run(Thread.java:818)
我也在 okhttp 网站上找到了这个,但它也不起作用:
public OkHttpClient.Builder sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager 信任管理器) 设置用于保护 HTTPS 连接的套接字工厂和信任管理器。如果未设置,将使用系统默认值。 大多数应用程序不应调用此方法,而是使用系统默认值。这些类包括特殊的优化,如果实现被修饰,这些优化可能会丢失。
如有必要,您可以使用以下代码自行创建和配置默认值:
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager))
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] trustManager , null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager);
.build();
【问题讨论】:
【参考方案1】:我的 android 应用程序(以及我的 Spring Boot 后端服务器)也有类似的问题。我认为您的问题与您使用的是自签名证书有关。解决方案是在应用的 assets 文件夹中嵌入一个包含受信任证书的信任管理器(PKCS12 格式)。
1.在资产文件夹中添加您的密钥库和证书:
2. 然后以这种方式使用您的嵌入式信任管理器配置 OkHttpClient: (用你的密码修改)
fun getOkHttpClient(context: Context): OkHttpClient
val password = "keystore_password".toCharArray()
val keyStore = KeyStore
.getInstance("PKCS12").apply
load(context.assets.open("trust_store.p12"), password)
val trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm())
.apply init(keyStore)
val keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm())
.apply init(keyStore, password)
val sslContext = SSLContext.getInstance("SSL")
.apply
init(keyManagerFactory.keyManagers, trustManagerFactory.trustManagers, SecureRandom())
return OkHttpClient.Builder()
.sslSocketFactory(sslContext.socketFactory,
trustManagerFactory.trustManagers[0] as X509TrustManager)
.hostnameVerifier hostname, _ -> hostname == apiHostname // Return true if you want to trust all hostnames
.build()
如果您想信任所有主机名,只需在 hostnameVerifier
功能块中返回 true,但我不建议您这样做,因为它会使您的应用面临安全威胁。
请注意,使用自定义信任库时,您的应用将仅信任该信任库中包含的证书。
【讨论】:
以上是关于信任锚不仅在设备上找到,而且在模拟器上运行?的主要内容,如果未能解决你的问题,请参考以下文章