首页 > 解决方案 > 在获得即时证书并禁用证书检查后,仍然无法找到证书路径的信任锚

问题描述

我正在尝试一个 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();
}
}

我究竟做错了什么?

标签: androidsslexoplayer

解决方案


在下面尝试(忽略 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/5685911https://developer.android.com/training/articles/security-ssl#java


推荐阅读