未找到 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());
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
与接受的答案相反,您不需要需要自定义信任管理器,您需要修复服务器配置!
在连接到 Apache 服务器时,我遇到了同样的问题,并且未正确安装 dynadot/alphassl 证书。我正在使用 HttpsUrlConnection (Java/Android) 进行连接,该连接抛出异常 -
实际问题是服务器配置错误 - 使用 http://www.digicert.com/help/ 或类似的,它甚至会告诉你解决方案:
“该证书不是由受信任的机构签名的(检查 Mozilla 的根存储)。如果你购买了证书来自一个受信任的机构,您可能只需要安装一个或多个中间证书,请联系您的证书提供商以获取针对您的服务器平台执行此操作的帮助。”
您还可以使用 openssl 检查证书:
openssl s_client -debug -connect www.thedomaintocheck.com:443
您可能会看到:
验证返回代码:21(无法验证第一个证书) )
并且,在输出的前面:
证书链将仅包含 1 个元素(您的证书):
...但应将链中的签名权限引用回 Android 信任的签名权限(Verisign、 GlobalSign 等):
配置服务器的说明(和中间证书)通常由颁发证书的机构提供,例如:http://www.alphassl.com/support/install-root-certificate.html
安装证书颁发者提供的中间证书后,我现在没有错误连接使用HttpsUrlConnection。
Contrary to the accepted answer you do not need a custom trust manager, you need to fix your server configuration!
I hit the same problem while connecting to an Apache server with an incorrectly installed dynadot/alphassl certificate. I'm connecting using HttpsUrlConnection (Java/Android), which was throwing -
The actual problem is a server misconfiguration - test it with http://www.digicert.com/help/ or similar, and it will even tell you the solution:
"The certificate is not signed by a trusted authority (checking against Mozilla's root store). If you bought the certificate from a trusted authority, you probably just need to install one or more Intermediate certificates. Contact your certificate provider for assistance doing this for your server platform."
You can also check the certificate with openssl:
openssl s_client -debug -connect www.thedomaintocheck.com:443
You'll probably see:
Verify return code: 21 (unable to verify the first certificate)
and, earlier in the output:
The certificate chain will only contain 1 element (your certificate):
... but should reference the signing authorities in a chain back to one which is trusted by Android (Verisign, GlobalSign, etc):
Instructions (and the intermediate certificates) for configuring your server are usually provided by the authority that issued your certificate, for example: http://www.alphassl.com/support/install-root-certificate.html
After installing the intermediate certificates provided by my certificate issuer I now have no errors when connecting using HttpsUrlConnection.
@Chrispix 的解决方案很危险! 信任所有证书允许任何人进行中间人攻击!只需将任何证书发送给客户端,客户端就会接受它!
将您的证书添加到自定义信任管理器,如本文所述:通过 HTTPS 使用 HttpClient 信任所有证书
虽然使用自定义证书建立安全连接有点复杂,但它会为您带来所需的 ssl 加密安全无中间人攻击的危险!
The solution of @Chrispix is dangerous! Trusting all certificates allows anybody to do a man in the middle attack! Just send ANY certificate to the client and it will accept it!
Add your certificate(s) to a custom trust manager like described in this post: Trusting all certificates using HttpClient over HTTPS
Although it is a bit more complex to establish a secure connection with a custom certificate, it will bring you the wanted ssl encryption security without the danger of man in the middle attack!
根据最新 Android 文档进行更新(2017 年 3 月):
当您收到此类错误时:
问题可能是以下原因之一:
解决方案是教导
HttpsURLConnection
信任一组特定的 CA。如何?请检查 https://developer.android.com/training/articles/security -ssl.html#CommonProblems其他使用
com.loopj.android:android-async-http
库中的AsyncHTTPClient
的人,请检查设置 AsyncHttpClient 以使用 HTTPS。Update based on latest Android documentation (March 2017):
When you get this type of error:
the issue could be one of the following:
The solution is to teach
HttpsURLConnection
to trust a specific set of CAs. How? Please check https://developer.android.com/training/articles/security-ssl.html#CommonProblemsOthers who are using
AsyncHTTPClient
fromcom.loopj.android:android-async-http
library, please check Setup AsyncHttpClient to use HTTPS.您可以在运行时信任特定证书。
只需从服务器下载它,放入资产并使用 ssl-utils-android 加载:
在上面的示例中,我使用了
OkHttpClient
,但SSLContext
可以与 Java 中的任何客户端一起使用。如果您有任何疑问,请随时提问。我是这个小图书馆的作者。
You can trust particular certificate at runtime.
Just download it from server, put in assets and load like this using ssl-utils-android:
In the example above I used
OkHttpClient
butSSLContext
can be used with any client in Java.If you have any questions feel free to ask. I'm the author of this small library.
回复很旧的帖子。但也许它会对一些新手有所帮助,如果上述方法都不起作用的话。
解释:我知道没有人想要垃圾解释;而不是解决方案。但在一个班轮中,您正尝试从本地计算机访问不信任您计算机的远程计算机的服务。您请求需要获得远程服务器的信任。
解决方案:以下解决方案假设您满足以下条件:
步骤:
您需要一个 .keystore 扩展文件来注册您的应用程序。如果您不知道如何创建 .keystore 文件;然后按照以下创建 .keystore 文件部分进行操作,或者跳至下一部分签署 Apk 文件
创建 .keystore 文件
打开 Android Studio。单击顶部菜单“构建”>“构建”生成签名的 APK。在下一个窗口中,单击创建新...按钮。在新窗口中,请在所有字段中输入数据。请记住我建议的两个密码字段应该具有相同的密码;不要使用不同的密码;还要记住最顶部字段密钥存储路径:的保存路径。输入所有字段后,单击“确定”按钮。
签署 Apk 文件
现在您需要使用刚刚创建的 .keystore 文件构建一个签名的应用程序。按照以下步骤
选择现有...
按钮密钥库密码
和密钥密码
字段使用相同的密码。还要输入别名build.gradle
文件中的设置可能会有所不同,您需要选择Build Types
和Flavors
。Build Types
,从下拉列表中选择release
对于
Flavors
,但这取决于您在build.gradle< 中的设置/代码> 文件。从此字段中选择
暂存
。我在build.gradle
中使用了以下设置,您可以使用与我相同的设置,但请确保将applicationId
更改为您的包名称单击底部两个
Signature Versions
复选框,然后单击Finish
按钮。即将完成:
所有的努力都已完成,现在是真理的运动。为了访问通过代理备份的临时服务器,您需要在实际测试的 Android 设备中进行一些设置。
Android 设备中的代理设置:
修改网络
高级选项
如果您看不到代理主机名
字段,代理主机名
中输入您要连接的主机IP或名称。典型的登台服务器将命名为stg.api.mygoodcompany.com
9502
保存
> 按钮最后一站:
请记住,我们在签署 APK 文件部分中生成了签名的 apk 文件。现在是时候安装该 APK 文件了。
adb install
apk 文件的名称
adb command not found
。输入完整路径C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe
install
apk 文件的名称
我希望问题能够得到解决。如果没有请给我留言。
萨拉姆!
Replying to very old post. But maybe it will help some newbie and if non of the above works out.
Explanation: I know nobody wants explanation crap; rather the solution. But in one liner, you are trying to access a service from your local machine to a remote machine which does not trust your machine. You request need to gain the trust from remote server.
Solution: The following solution assumes that you have the following conditions met
Steps:
You need a .keystore extension file to signup your app. If you don't know how to create .keystore file; then follow along with the following section Create .keystore file or otherwise skip to next section Sign Apk File
Create .keystore file
Open Android Studio. Click top menu Build > Generate Signed APK. In the next window click the Create new... button. In the new window, please input in data in all fields. Remember the two Password field i recommend should have the same password; don't use different password; and also remember the save path at top most field Key store path:. After you input all the field click OK button.
Sign Apk File
Now you need to build a signed app with the .keystore file you just created. Follow these steps
Choose existing...
buttonKey store password
andKey password
fields. Also enter the aliasbuild.gradle
files, you need to selectBuild Types
andFlavors
.Build Types
chooserelease
from the dropdownFor
Flavors
however it will depends on your settings inbuild.gradle
file. Choosestaging
from this field. I used the following settings in thebuild.gradle
, you can use the same as mine, but make sure you change theapplicationId
to your package nameClick the bottom two
Signature Versions
checkboxes and clickFinish
button.Almost There:
All the hardwork is done, now the movement of truth. Inorder to access the Staging server backed-up by proxy, you need to make some setting in your real testing Android devices.
Proxy Setting in Android Device:
Modify network
Advanced options
if you can't see theProxy Hostname
fieldProxy Hostname
enter the host IP or name you want to connect. A typical staging server will be named asstg.api.mygoodcompany.com
9502
Save
buttonOne Last Stop:
Remember we generated the signed apk file in Sign APK File section. Now is the time to install that APK file.
adb install
name of the apk file
adb command not found
. Enter the full path asC:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe
install
name of the apk file
I hope the problem might be solved. If not please leave me a comments.
Salam!
使用 https://www.ssllabs.com/ssltest/ 测试域。
Shihab Uddin 在 Kotlin 中的解决方案。
如果您使用
Glide
也会出现同样的错误,图像不会显示。要克服它,请参阅 Glide - javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException:未找到证书路径的信任锚和如何为 glide 设置 OkHttpClient。build.gradle:
更新
我还在 API 16 模拟器上遇到了另一个错误:
阅读1 和2,我更改了代码:
我还从
MyApplication
中删除了这些行:但是 library 添加3.4 Mb 到 apk。
Use https://www.ssllabs.com/ssltest/ to test a domain.
The solution of Shihab Uddin in Kotlin.
The same error will also appear if you use
Glide
, images won't show. To overcome it see Glide - javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found and How to set OkHttpClient for glide.build.gradle:
UPDATE
I also got another error on API 16 emulator:
Reading 1 and 2, I changed code so:
I also removed these lines from
MyApplication
:But the library adds 3.4 Mb to apk.
我在尝试使用使用自签名证书来公开其测试版本的外部 Web 服务时遇到了同样的问题。以下是我用于全局解决该问题的步骤(它将应用您正在使用的任何框架:Retrofit、oKhttp、HttpUrlConnection)
挂锁符号
,然后是详细信息然后
导出
并选择der
格式)res/raw/dev_thedomain_private.der
下创建一个安全配置文件>resources/xml
你就完成了!该证书现在将被信任...
I had the same problem while trying to consume an external webservice that uses a self signed certificate for exposing its testing version. Here are the steps I've used to solve the issue globally (it will apply whatever the framework you're using : Retrofit, oKhttp, HttpUrlConnection)
padlock symbol
near the url, thendetails
thenexport
and select theder
format)res/raw/dev_thedomain_private.der
resources/xml
You're done ! The certificate will be trusted now...
我遇到了同样的问题,我发现我提供的证书 .crt 文件缺少中间证书。因此,我向服务器管理员询问了所有 .crt 文件,然后以相反的顺序将它们连接起来。
前任。
1.根.crt
2. 交互
3.
我在windows中执行的 myCrt.crt
复制 Inter.crt + Root.crt newCertificate.crt
(这里我忽略了 myCrt.crt)
然后我通过输入流将 newCertificate.crt 文件提供到代码中。
工作完成了。
I had the same problem what i found was that the certificate .crt file i provided missing an intermediate certificate. So I asked all .crt files from my server admin, then concatinated them in reverse order.
Ex.
1. Root.crt
2. Inter.crt
3. myCrt.crt
in windows i executed
copy Inter.crt + Root.crt newCertificate.crt
(Here i ignored myCrt.crt)
Then i provided newCertificate.crt file into code via inputstream.
Work done.
我知道您不需要信任所有证书,但就我而言,我在一些调试环境中遇到了问题,在这些环境中我们有自签名证书,我需要一个肮脏的解决方案。
我所要做的就是更改
sslContext
的初始化,其中创建
trustAllCerts
如下:希望这会派上用场。
I know that you don't need to trust all certificates but in my case I had problems with some debugging environments where we had self-signed certificates and I needed a dirty solution.
All I had to do was to change the initialization of the
sslContext
where
trustAllCerts
was created like this:Hope that this will come in handy.
就我而言, root &中间证书已成功安装,但我仍然收到“未找到证书路径的信任锚”。例外!。在挖掘 android 文档后,发现默认情况下,安全连接(使用 TLS 和 HTTPS 等协议的所有应用都信任预装的系统 CA,并且针对 Android 6.0(API 级别 23)及更低版本的应用也默认信任用户添加的 CA 存储。如果您的应用程序在 api 级别高于 23 的操作系统上运行,您应该通过将其地址添加到 network_security_config 来显式允许应用程序信任用户添加的 CA,如下所示:
In my case, the root & intermediate certificates was successfully installed but I still got "Trust anchor for certification path not found." exception!. After digging the android document, found out that by default, secure connections (using protocols like TLS and HTTPS) from all apps trust the pre-installed system CAs, and apps targeting Android 6.0 (API level 23) and lower also trust the user-added CA store by default. If your app running on a OS with api level higher than 23 you should explicitly allow the app to trust user-added CA by adding its address to network_security_config like bellow:
我收到的错误消息类似,但原因是自签名证书已过期。
当尝试使用 openssl 客户端时,它给出了当我从 Firefox 检查证书对话框时被忽略的原因。
因此,一般来说,如果证书存在于密钥库中并且其“有效”,则会出现此错误。
The error message I was getting was similar but the reason was that the self signed certificate had expired.
When the openssl client was attempted, it gave me the reason which was overlooked when I was checking the certificate dialog from firefox.
So in general, if the certificate is there in the keystore and its "VALID", this error will go off.
我在从 Android 客户端连接到 Kurento 服务器时遇到了同样的问题。
Kurento服务器使用jks证书,所以我必须将pem转换为它。
作为转换的输入,我使用了 cert.pem 文件,它导致了此类错误。
但如果使用 fullchain.pem 而不是 cert.pem - 一切都可以。
I had the same problem while connecting from Android client to Kurento server.
Kurento server use jks certificates, so I had to convert pem to it.
As input for conversion I used cert.pem file and it lead to such errors.
But if use fullchain.pem instead of cert.pem - all is OK.
发生信任锚错误的原因有很多。对我来说,这只是我试图访问
https://example.com/
而不是https://www.example.com/
。因此,在开始构建您自己的信任管理器之前,您可能需要仔细检查您的 URL(就像我所做的那样)。
The Trust anchor error can happen for a lot of reasons. For me it was simply that I was trying to access
https://example.com/
instead ofhttps://www.example.com/
.So you might want to double-check your URLs before starting to build your own Trust Manager (like I did).
正如其他人已经提到的,该证书不受信任。解决方案是获取该证书并将其作为可信证书包含在您的 http 客户端中。
提取服务器证书,如下所示: 使用 openssl从服务器获取证书
然后为 HttpsURLConnection 客户端创建 SSLSocketFactory,如下所示。
上面的例子是众所周知的 HttpsURLConnection。但是,如果您使用不同的客户端,这可能也很有用,因为它包含近 50 个用于配置 ssl 的不同 http 客户端的列表,请参阅此处:示例 http 客户端 ssl 配置
我需要告诉您,上面的代码片段基于我在此处提供的库:GitHub - SSLContext Kickstart 可以将以下代码片段包含到您的 gradle 构建文件中:
As others already mentioned the certificate is not trusted. The solution would be to obtain that certificate and include it as a trusted certificate within your http client.
Extract the server certificate as shown here: Using openssl to get the certificate from a server
And then create a SSLSocketFactory for the HttpsURLConnection client as shown below.
The above example is for the well known HttpsURLConnection. However if you are using a different client, this might be also usefull as it contains a list of almost 50 different http clients for configuring ssl, see here: Example http client ssl configuration
I need tell that the above snippet is based on a library which I provide here: GitHub - SSLContext Kickstart which can be included with the following snippet to your gradle build file:
在 Gingerbread 手机中,我总是收到此错误:
未找到 Android SSL 连接的信任锚
,即使我设置为依赖我的证书也是如此。这是我使用的代码(使用 Scala 语言):
这是连接代码:
基本上,我设置为信任我的自定义证书。如果失败,那么我会禁用安全性。这不是最好的选择,但据我所知,对于旧的和有缺陷的手机来说,这是唯一的选择。
这个示例代码可以很容易地翻译成Java。
In Gingerbread phones, I always get this error:
Trust Anchor not found for Android SSL Connection
, even if I setup to rely on my certificate.Here is the code I use (in Scala language):
and here is the connection code:
Basically, I setup to trust on my custom certificate. If that fails, then I disable security. This is not the best option, but the only choice I know with old and buggy phones.
This sample code, can be easily translated into Java.
我也遇到过类似的问题,并且我完全排除了信任所有来源的策略。
我在这里分享我的解决方案应用于在 Kotlin 中实现的应用程序,
我首先建议使用 以下网站获取有关证书及其有效性的信息
如果该证书未在 Android 默认信任存储区中显示为“接受的颁发者” ,我们必须获得该证书并将其合并到应用程序中以创建自定义信任存储
在我的案例中,理想的解决方案是创建一个结合了自定义和 Android 默认信任存储的高级信任管理器
这里他公开了高级 信任存储用于配置他与 Retrofit 一起使用的 OkHttpClient 的代码。
这样,我就可以使用自签名证书与服务器进行通信,并使用受信任的证书实体颁发的证书与其他服务器进行通信
就是这样,我希望它可以帮助别人。
I have had a similar problem and I have completely ruled out the strategy of trusting all sources.
I share here my solution applied to an application implemented in Kotlin
I would first recommend using the following website to obtain information about the certificate and its validity
If it does not appear as an 'Accepted Issuers' in the Android default trust store, we must get that certificate and incorporate it into the application to create a custom trust store
The ideal solution in my case was to create a high-level Trust Manager that combines the custom and the Android default trust store
Here he exposes the high level code used to configure the OkHttpClient that he used with Retrofit.
In this way, I could communicate with the server with a self-signed certificate and with other servers with a certificate issued by a trusted certification entity
This is it, I hope it can help someone.
我知道这是一篇非常旧的文章,但我在尝试解决我的信任锚问题时看到了这篇文章。我已经发布了我如何修复它。如果您已预安装根 CA,则需要将配置添加到清单中。
https://stackoverflow.com/a/60102517/114265
I know this is a very old article, but I came across this article when trying to solve my trust anchor issues. I have posted how I fixed it. If you have pre-installed your Root CA you need to add a configuration to the manifest.
https://stackoverflow.com/a/60102517/114265
有时,当管理员错误地设置证书时会发生这种情况
在这里查看网址
https://www.sslshopper.com/ssl-checker.html
就我而言,出现错误
证书在所有 Web 浏览器中不受信任。您可能需要安装中间/链证书以将其链接到受信任的根证书。了解有关此错误的更多信息。您可以按照适用于您的服务器平台的 GlobalSign 证书安装说明来修复此问题。请注意有关中级证书的部分。
Sometimes it happens when admins setup the certificate incorrectly
Check URL here
https://www.sslshopper.com/ssl-checker.html
In my case, there was an error
The certificate is not trusted in all web browsers. You may need to install an Intermediate/chain certificate to link it to a trusted root certificate. Learn more about this error. You can fix this by following GlobalSign's Certificate Installation Instructions for your server platform. Pay attention to the parts about Intermediate certificates.
就我而言,网站中的证书是正确的(颁发者 = GlobalSign RSA OV SSL CA 2018),但我下载的证书文件是错误的,因为防病毒软件“拦截”了证书并将新的不同证书传递给从浏览器下载(颁发者 = ESET SSL Filter CA)!!!
检查您的证书文件是否具有正确的颁发者。
In my case, the certificate in the website was correct (Issuer = GlobalSign RSA OV SSL CA 2018), but the certificate file I was downloading was wrong, because of the Antivirus that was "intercepting" the certificate and deliverying a new different certificate to download fron the browsers (Issuer = ESET SSL Filter CA) !!!
Check your certificate file has the correct issuer.
就我而言,这是在更新到 Android 8.0 后发生的。 Android 设置为信任的自签名证书使用签名算法 SHA1withRSA。切换到新的证书,使用签名算法 SHA256withRSA 解决了该问题。
In my case this was happening after update to Android 8.0. The self-signed certificate Android was set to trust was using signature algorithm SHA1withRSA. Switching to a new cert, using signature algorithm SHA256withRSA fixed the problem.
我使用这些方法,其中一种方法在上面的解决方案中对我有用:
第一:
第二:
和:
将此库放入您的类路径:
确保在您的类中调用它们
I use these methods that one of them is in solutions above works for me :
First:
Second:
and:
put this libraries to your classpath:
be sure that you call them in your class
联系您的客户,如下所示
var httpClient = new HttpClient(new System.Net.Http.HttpClientHandler());
将 https 更改为 http
Relpcae your clicent Like below
var httpClient = new HttpClient(new System.Net.Http.HttpClientHandler());
Change https to http