CertPathValidatorException:信任锚证书路径未找到 - 改造Android的 [英] CertPathValidatorException : Trust anchor for certificate path not found - Retrofit Android
问题描述
我创建一个Android应用程序,它使用了 HTTPS
与服务器进行通信。我使用加装
和 OkHttp
制作的请求。这些作品的罚款标准 HTTP
请求。以下是我遵循的步骤。
I am creating an android application which uses https
for communication with the server. I am using retrofit
and OkHttp
for making requests. These works fine for standard http
requests. The following are the steps that I followed.
第1步: 后天从服务器使用该命令的证书文件
Step 1 : Acquired the cert file from the server using the command
echo -n | openssl s_client -connect api.****.tk:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > gtux.cert
第二步: 通过使用下面的命令转换的证书给BKS格式
Step 2 : Converted the cert to a BKS format by using the following commands
keytool -importcert -v -trustcacerts -file "gtux.cert" -alias imeto_alias -keystore "my_keystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-146.jar" -storetype BKS
它问我要密码,并成功创建了文件。
It asked me for password and the file was successfully created.
第三步:
创建OkHttpClient并使用相同的用于制造https请求
Create a OkHttpClient and use the same for making https requests
public class MySSLTrust {
public static OkHttpClient trustcert(Context context){
OkHttpClient okHttpClient = new OkHttpClient();
try {
KeyStore ksTrust = KeyStore.getInstance("BKS");
InputStream instream = context.getResources().openRawResource(R.raw.my_keystore);
ksTrust.load(instream, "secret".toCharArray());
// TrustManager decides which certificate authorities to use.
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ksTrust);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException e) {
e.printStackTrace();
}
return okHttpClient;
}
}
第四步:
RestAdapter已被创建
RestAdapter has to be created
RestAdapter.Builder()
.setRequestInterceptor(intercept)
.setEndpoint("https://api.****.tk")
.setClient(new OkClient(this))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setLog(new AndroidLog("RETROFIT"))
.build();
但是运行程序的时候,是扔我终于当 CertPathValidatorException:找不到证书路径信任锚
。请帮我解决这个问题。谢谢。
But finally when run the app it is throwing me CertPathValidatorException : Trust anchor for certificate path not found
. Please help me to solve this. Thank you.
其他失败尝试: 试图在我的Xperia Z2安装证书,它说安装了文件,但是当我运行的应用程序相同的异常。
Other failure attempts : Tried to install the certificate in my Xperia Z2 and it says the file was installed but when i run the app the same exception is thrown.
错误日志 下面是我得到了执行错误日志...
Error Log Here is the error log that I got on executing...
粘贴有那么这将是易于阅读。
Pasted there so that it will be easy to read..
推荐答案
好了,我懂了工作使用的 Android开发者指南。
Okay, I got it working using Android Developers guide.
正如OP,我试图使用改造和 OkHttp 连接到一个自签名的SSL功能的服务器。
Just as OP, I'm trying to use Retrofit and OkHttp to connect to a self-signed SSL-enabled server.
下面是该得到的东西的工作(我已经删除了try / catch块)的code:
Here's the code that got things working (I've removed the try/catch blocks):
public static RestAdapter createAdapter(Context context) {
OkHttpClient okHttpClient = new OkHttpClient();
// loading CAs from an InputStream
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream cert = context.getResources().openRawResource(R.raw.my_cert);
Certificate ca;
try {
ca = cf.generateCertificate(cert);
} finally { cert.close(); }
// creating a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// creating a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// creating an SSLSocketFactory that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
// creating a RestAdapter using the custom client
return new RestAdapter.Builder()
.setEndpoint(UrlRepository.API_BASE)
.setClient(new OkClient(okHttpClient))
.build();
}
要帮助调试,我还添加了 .setLogLevel(RestAdapter.LogLevel.FULL)
来我RestAdapter创建命令,我可以看到它的连接,并获得从响应服务器。
To help in debugging, I also added .setLogLevel(RestAdapter.LogLevel.FULL)
to my RestAdapter creation commands and I could see it connecting and getting the response from the server.
时采取了我原来的 .CRT 保存在文件主/ RES /生
。
在 .CRT 文件,又名证书,是创建的两个文件之一,当您创建使用证书的OpenSSL
。通常,它是一个.CRT或.cert文件,而另一个是一个.key文件。
All it took was my original .crt file saved in main/res/raw
.
The .crt file, aka the certificate, is one of the two files created when you create a certificate using openssl
. Generally, it is a .crt or .cert file, while the other is a .key file.
AFAIK,.CRT文件是以您的公钥和.key文件是你的私钥。
Afaik, the .crt file is your public key and the .key file is your private key.
正如我所看到的,您已经有了一个 .cert 文件,尝试使用它。
As I can see, you already have a .cert file, try to use it.
对于那些读它的未来,只有有一个.pem文件,根据这个答案,你只需要这个转换一个到另一个:
For those that read it in the future and only have a .pem file, according to this answer, you only need this to convert one to the other:
openssl x509 -outform der -in your-cert.pem -out your-cert.crt
请接受这个答案,如果你的作品。 :)
Please accept this answer if it works for you. :)
这篇关于CertPathValidatorException:信任锚证书路径未找到 - 改造Android的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!