未find适用于Android SSL连接的信任锚

我试图连接到运行godaddy 256位SSL证书的IIS6框,我收到错误:

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 

一直试图确定是什么原因造成的,但现在画空白。

这是我如何连接:

 HttpsURLConnection conn; conn = (HttpsURLConnection) (new URL(mURL)).openConnection(); conn.setConnectTimeout(20000); conn.setDoInput(true); conn.setDoOutput(true); conn.connect(); String tempString = toString(conn.getInputStream()); 

@Chrispix的解决scheme是危险的! 信任所有证书允许任何人在中间进攻中做一个人! 只要发送任何证书给客户,它会接受它!

将您的证书添加到自定义信任pipe理器(如本文中所述): 使用HttpClient通过HTTPS信任所有证书

另外与自定义证书build立安全连接会更加复杂一点,它将为您带来所需的sslencryption安全性,避免中间人攻击的危险!

与接受的答案相反,您不需要自定义信任pipe理器,您需要修复您的服务器configuration!

在连接到Apache服务器时,如果安装的dynadot / alphassl证书不正确,我遇到同样的问题。 我正在使用HttpsUrlConnection(Java / Android)进行连接,

 javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 

实际的问题是服务器configuration错误 – 用http://www.digicert.com/help/或类似的方法进行testing,它甚至会告诉你解决scheme:;

“证书不是由可信任的权威机构签署的(检查Mozilla的根存储)如果您从可信任的机构购买证书, 您可能只需要安装一个或多个中级证书即可 。服务器平台“。

您也可以使用openssl检查证书:

openssl s_client -debug -connect www.thedomaintocheck.com:443

你可能会看到:

Verify return code: 21 (unable to verify the first certificate)

并且在输出的早些时候:

 depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com verify error:num=27:certificate not trusted verify return:1 depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com verify error:num=21:unable to verify the first certificate` 

证书链只包含1个元素(您的证书):

 Certificate chain 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com i:/O=AlphaSSL/CN=AlphaSSL CA - G2 

…但是应该将链接中的签名机构引用回Android(Verisign,GlobalSign等)信任的链接:

 Certificate chain 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com i:/O=AlphaSSL/CN=AlphaSSL CA - G2 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2 i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA 

用于configuration服务器的说明(和中间证书)通常由颁发证书的机构提供,例如: http : //www.alphassl.com/support/install-root-certificate.html

在安装由我的证书颁发者提供的中间证书之后,我现在在使用HttpsUrlConnection连接时没有错误。

您可以在运行时信任特定的证书。
只需要从服务器上下载,使用ssl-utils-android就可以像下面这样加载资源和加载:

 OkHttpClient client = new OkHttpClient(); SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer"); client.setSslSocketFactory(sslContext.getSocketFactory()); 

在上面的例子中,我使用了OkHttpClientSSLContext可以用于Java中的任何客户端。

如果你有任何问题随时问。 我是这个小型图书馆的作者。

我得到的错误信息是相似的,但原因是自签名证书已过期。 当openssl客户端尝试时,它给了我从firefox检查证书对话框时被忽略的原因。

所以通常情况下,如果证书存在于密钥库中并且其“VALID”,那么这个错误将会消失。

根据最新的Android文档进行更新(2017年3月):

当你得到这种types的错误:

 javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374) at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209) at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478) at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433) at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290) at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240) at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282) at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177) at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271) 

该问题可能是下列之一:

  1. 颁发服务器证书的CA是未知的
  2. 服务器证书不是由CA签名的,而是自签名的
  3. 服务器configuration缺less中间CA.

解决方法是教HttpsURLConnection信任一组特定的CA. 怎么样? 请检查https://developer.android.com/training/articles/security-ssl.html#CommonProblems

其他使用com.loopj.android:android-async-http库中的AsyncHTTPClient ,请检查Setup AsyncHttpClient以使用HTTPS 。

我遇到了同样的问题,我发现我提供的证书.crt文件缺less中间证书。 所以我问我的服务器pipe理员的所有.crt文件,然后concatinated他们倒序。

防爆。 1. Root.crt 2. Inter.crt 3. myCrt.crt

在Windows中我执行复制Inter.crt + Root.crt newCertificate.crt

(这里我忽略了myCrt.crt)

然后我通过inputstream将newCertificate.crt文件提供给代码。 完工。

从Android客户端连接到Kurento服务器时,我遇到同样的问题。 Kurento服务器使用jks证书,所以我不得不将pem转换成它。 作为转换input,我使用了cert.pem文件,并导致这样的错误。 但是,如果使用fullchain.pem而不是cert.pem – 一切正常。

在姜饼手机,我总是得到这个错误: Trust Anchor not found for Android SSL Connection ,即使我设置依靠我的证书。

这里是我使用的代码(用Scala语言):

 object Security { private def createCtxSsl(ctx: Context) = { val cer = { val is = ctx.getAssets.open("mycertificate.crt") try CertificateFactory.getInstance("X.509").generateCertificate(is) finally is.close() } val key = KeyStore.getInstance(KeyStore.getDefaultType) key.load(null, null) key.setCertificateEntry("ca", cer) val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm) tmf.init(key) val c = SSLContext.getInstance("TLS") c.init(null, tmf.getTrustManagers, null) c } def prepare(url: HttpURLConnection)(implicit ctx: Context) { url match { case https: HttpsURLConnection ⇒ val cSsl = ctxSsl match { case None ⇒ val res = createCtxSsl(ctx) ctxSsl = Some(res) res case Some(c) ⇒ c } https.setSSLSocketFactory(cSsl.getSocketFactory) case _ ⇒ } } def noSecurity(url: HttpURLConnection) { url match { case https: HttpsURLConnection ⇒ https.setHostnameVerifier(new HostnameVerifier { override def verify(hostname: String, session: SSLSession) = true }) case _ ⇒ } } } 

这里是连接代码:

 def connect(securize: HttpURLConnection ⇒ Unit) { val conn = url.openConnection().asInstanceOf[HttpURLConnection] securize(conn) conn.connect(); .... } try { connect(Security.prepare) } catch { case ex: SSLHandshakeException /*if ex.getMessage != null && ex.getMessage.contains("Trust anchor for certification path not found")*/ ⇒ connect(Security.noSecurity) } 

基本上,我设置信任我的自定义证书。 如果失败了,那么我禁用安全。 这不是最好的select,但我知道与旧的和越野车手机的唯一select。

这个示例代码可以很容易地转换成Java。

 **Set proper alias name** CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC"); X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream); String alias = cert.getSubjectX500Principal().getName(); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null); trustStore.setCertificateEntry(alias, cert);