The reason this occur is the JVM/Dalvik haven't not confidence in the CA certificates in the system or in the user certificate stores.
To fix this with Retrofit, If you are used okhttp, with another client it's very similar.
You've to do:
A). Create a cert store contain public Key of CA. To do this you need to launch next script for *nix.
You need openssl install in your machine, and download from https://www.bouncycastle.org/ the jar bcprov-jdk16-1.46.jar. Download this version not
other, the version 1.5x is not compatible with android 4.0.4.
#!/bin/bash
if [ -z $1 ]; then
echo "Usage: cert2Android<CA cert PEM file>"
exit 1
fi
CACERT=$1
BCJAR=bcprov-jdk16-1.46.jar
TRUSTSTORE=mytruststore.bks
ALIAS=`openssl x509 -inform PEM -subject_hash -noout -in $CACERT`
if [ -f $TRUSTSTORE ]; then
rm $TRUSTSTORE || exit 1
fi
echo "Adding certificate to $TRUSTSTORE..."
keytool -import -v -trustcacerts -alias $ALIAS
-file $CACERT
-keystore $TRUSTSTORE -storetype BKS
-providerclass org.bouncycastle.jce.provider.BouncyCastleProvider
-providerpath $BCJAR
-storepass secret
echo ""
echo "Added '$CACERT' with alias '$ALIAS' to $TRUSTSTORE..."
B). Copy the file truststore mytruststore.bks in res/raw of your project
C). Setting SSLContext of the connection:
.............
okHttpClient = new OkHttpClient();
try {
KeyStore ksTrust = KeyStore.getInstance("BKS");
InputStream instream = context.getResources().openRawResource(R.raw.mytruststore);
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();
}
.................
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…