无法验证证书签名?

时间:2011-09-28 18:53:50

标签: android https x509certificate

我使用此端Self signed SSL

的SSL套接字和Trustmanager

但我不断收到以下错误:

  

09-28 19:52:41.942:WARN / System.err(10101):javax.net.ssl.SSLHandshakeException:org.bouncycastle.jce.exception.ExtCertPathValidatorException:无法验证证书签名。

有什么问题? 我已经在stackoverflow上检查了不同的帖子,但我似乎无法让它工作。

我的代码:

SchemeRegistry schemeRegistry = new SchemeRegistry();

// http scheme

schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

// https scheme

schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
params = new BasicHttpParams();
params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 1);
params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(1));
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "utf8");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope("www.example.com", AuthScope.ANY_PORT),
    new UsernamePasswordCredentials("user", "password"));
clientConnectionManager = new ThreadSafeClientConnManager(params, schemeRegistry);
context = new BasicHttpContext();
context.setAttribute("http.auth.credentials-provider", credentialsProvider);

DefaultHttpClient client = new DefaultHttpClient(clientConnectionManager, params);

HttpGet get = new HttpGet("https://www.example.com/web/restricted/form/formelement=512663");
HttpResponse response = client.execute(get, context);

Log.w("Response ","Status line : "+ response.toString());

5 个答案:

答案 0 :(得分:28)

正如迈克尔·列维所提到的,我之所以遇到这个例外的原因是我已经让我的Android模拟器开放了几天而且时钟已经远远不同步了。一旦我重新启动模拟器,异常就消失了。

答案 1 :(得分:2)

很可能服务器返回了您不信任的权限的证书链。 (表示:您的设备不知道授权证书是否可信) 解决方案:仔细检查来自HTTPS网站的证书,并将相应的权限添加到您的信任库 - 但这部分似乎很棘手

(这里有一些解释: http://groups.google.com/group/android-security-discuss/browse_thread/thread/0bf726de4f5275a3/391b900631d7f358

答案 2 :(得分:2)

就我而言,在Android 4和5上出现了以下错误:

原因: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: 无法验证证书:证书于5月30日星期六过期 10:48:38 GMT + 00:00 2020(相比之下,星期四8月13日11:47:00 GMT + 00:00 2020)

...

原因:java.security.cert.CertificateExpiredException: 证书于2020年5月30日星期六10:48:38 GMT + 00:00过期(与 星期四,八月13日11:47:00 GMT + 00:00 2020)

服务器出现证书错误(可能已过期)。

有关Retrofit的信息,请参见https://stackoverflow.com/a/60507560/2914140。如果您将Fuel用作REST库,请参见kotlin library that can do httpS connection without certificate verification (like curl --insecure)

您可以信任所有证书,但这很危险。

import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.security.cert.CertificateException

companion object {

    private val gson: Gson
    private val retrofit: Retrofit

    init {

        val okHttpClient = getOkHttpBuilder().build()

        gson = GsonBuilder().setLenient().create()

        retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    }

    private fun getOkHttpBuilder(): OkHttpClient.Builder =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            OkHttpClient().newBuilder()
        } else {
            getUnsafeOkHttpClient()
        }

    private fun getUnsafeOkHttpClient(): OkHttpClient.Builder =
        try {
            // Create a trust manager that does not validate certificate chains
            val trustAllCerts: Array<TrustManager> = arrayOf(
                object : X509TrustManager {
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    @Throws(CertificateException::class)
                    override fun checkServerTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
                }
            )
            // Install the all-trusting trust manager
            val sslContext: SSLContext = SSLContext.getInstance("SSL")
            sslContext.init(null, trustAllCerts, SecureRandom())
            // Create an ssl socket factory with our all-trusting manager
            val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
            val builder = OkHttpClient.Builder()
            builder.sslSocketFactory(sslSocketFactory,
                trustAllCerts[0] as X509TrustManager)
            builder.hostnameVerifier { _, _ -> true }
            builder
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
}

有关Android版本检查和Glide连接的信息,另请参见https://stackoverflow.com/a/60507560/2914140

答案 3 :(得分:0)

顺便说一句,我们可以轻松地重新产生这个错误 - 只需将手机的日期更改为几年。

注意:不同手机中的错误可能会略有不同。有些人可能会证明证书已过期。

答案 4 :(得分:0)

检查设备的时间,进行更正,然后再次检查。