android - 在获得即时证书并禁用证书检查后,仍然无法找到证书路径的信任锚
问题描述
我正在尝试一个 android 应用程序,其中HLS
我的nginx
服务器的链接被传递ExoPlayer
给播放。最初我一直得到
“原因:javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。”
错误之后在做研究时我发现了两种可能的解决方案。
第一个是按照https://knowledge.digicert.com/solution/SO17482.html中的步骤获取即时 CA 证书,第二个是禁用证书检查。我都尝试过,但仍然得到
“原因:javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。” 错误
我的播放器的代码是:
public class PlayerActivity extends AppCompatActivity implements VideoRendererEventListener {
String url;
private static final String TAG = "Twende Live";
private PlayerView simpleExoPlayerView;
private SimpleExoPlayer player;
private TextView resolutionTextView;
private final TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
} };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
//url = getIntent().getStringExtra("STREAM_URL");
try {
ProviderInstaller.installIfNeeded(getApplicationContext());
SSLContext sslContext;
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, null);
sslContext.createSSLEngine();
} catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException
| NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
Uri mp4VideoUri =Uri.parse(getIntent().getStringExtra("STREAM_URL"));
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); //test
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);
//create player
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
simpleExoPlayerView = new SimpleExoPlayerView(this);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
int h = simpleExoPlayerView.getResources().getConfiguration().screenHeightDp;
int w = simpleExoPlayerView.getResources().getConfiguration().screenWidthDp;
Log.v(TAG, "height : " + h + " weight: " + w);
////Set media controller
simpleExoPlayerView.setUseController(false);//set to true or false to see controllers
simpleExoPlayerView.requestFocus();
// Bind the player to the view.
simpleExoPlayerView.setPlayer(player);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "Twende"), bandwidthMeter);
MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
// Prepare the player with the source.
player.prepare(videoSource);
player.addListener(new ExoPlayer.EventListener() {
@Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
Log.v(TAG, "Listener-onTracksChanged... ");
}
@Override
public void onLoadingChanged(boolean isLoading) {
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.v(TAG, "Listener-onPlayerStateChanged..." + playbackState+"|||isDrawingCacheEnabled():"+simpleExoPlayerView.isDrawingCacheEnabled());
}
@Override
public void onRepeatModeChanged(int repeatMode) {
}
@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
@Override
public void onPlayerError(ExoPlaybackException error) {
Log.v(TAG, "Listener-onPlayerError...");
player.stop();
player.prepare(loopingSource);
player.setPlayWhenReady(true);
}
@Override
public void onPositionDiscontinuity(int reason) {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
@Override
public void onSeekProcessed() {
}
});
player.setPlayWhenReady(true); //run file/link when ready to play.
player.setVideoDebugListener(this);
}
@Override
public void onVideoEnabled(DecoderCounters counters) {
}
@Override
public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, long initializationDurationMs) {
}
@Override
public void onVideoInputFormatChanged(Format format) {
}
@Override
public void onDroppedFrames(int count, long elapsedMs) {
}
@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
Log.v(TAG, "onVideoSizeChanged [" + " width: " + width + " height: " + height + "]");
resolutionTextView.setText("RES:(WxH):" + width + "X" + height + "\n " + height + "p");//shows video info
}
@Override
public void onRenderedFirstFrame(Surface surface) {
}
@Override
public void onVideoDisabled(DecoderCounters counters) {
}
@Override
protected void onStop() {
super.onStop();
Log.v(TAG, "onStop()...");
}
@Override
protected void onStart() {
super.onStart();
Log.v(TAG, "onStart()...");
}
@Override
protected void onResume() {
super.onResume();
Log.v(TAG, "onResume()...");
}
@Override
protected void onPause() {
super.onPause();
Log.v(TAG, "onPause()...");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.v(TAG, "onDestroy()...");
player.release();
}
}
我究竟做错了什么?
解决方案
在下面尝试(忽略 HttpURLConnection 的证书):
//Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
{
//
}
public void checkServerTrusted(X509Certificate[] certs, String authType)
{
//
}
}
};
//Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (KeyManagementException|NoSuchAlgorithmException e) {
e.printStackTrace();
}
或者,如果您使用改造+OkHttp 并希望使用安全 (httpps) 连接,则创建 trustStore 文件(.BKS 文件)并将其传递给 TrustManagerFactory。TrustManager 决定使用哪些证书颁发机构。
有关更多详细信息,请参阅此https://stackoverflow.com/a/28785936/5685911和https://developer.android.com/training/articles/security-ssl#java。
推荐阅读
- python - 为什么numpy数组中相同索引选择的输出存在差异
- mysql - How to copy column values to a new SQL table, remove duplicates and create mappings?
- java - Why does java.util.Optional.ofNullable() expect @NonNullable?
- julia - 为值分配颜色
- sql - Try to make a view but have a problem ORA-00979: not a GROUP BY expression
- java - Flutter doctor --android-licenses problem
- python - xpath for scraping critic's reviews from rotten tomatoes
- python - how to verify a coupon using django framework and sqlite?
- flutter - Flutter load list with id
- pandas - My bokeh could runs fine, but outputs a blank chart. What am I doing wrong?