- Home /
Android https request returns SSLHandshakeException
I'm trying to send a simple https POST request through WWW class. I have to say beforehand than my server certificate is not trusted by a Certification Authority for the moment.
While on Editor, Webplayer and iOS the request works fine, ignoring the not trusted certificate, on Android device (Motorola Xoom in my case) i got an exeption:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Is there a way to let device ignore and go through it without a trusted certificate? Am I missing something?
any luck with this? i am trying to do the same with self signed SSL certificate
any luck with this yet? i am trying to do the same thing.
I wonder the same thing! Any leads at all? $$anonymous$$y certificate should be CA trusted but it's not working on Android. In iOS and editor i works fine.
i had the issue with trusted certificate as well which worked only on Android 2.3 and above.. not 2.2 did you have the same issue or it didn't work regardless of the OS version? it appears that on Android 2.2 and below it has an issue: http://stackoverflow.com/questions/9538714/android-2-2-ssl-bug-with-client-certificate
Thanks for your reply! Had 2.2, but it makes no difference when switching. Still same error. Tried 2.3, 3.0 and 4.0.
Answer by devluz · Mar 01, 2015 at 07:38 AM
Old question but I couldn't find any answer myself so I will leave my solution here in case someone else ends up here:
The problem is that androids HTTPS classes refuse to connect to systems with self signed/not trusted certificates. So you can get a certificate from one of the trusted CA's or you can change androids default trust manager which decides if your certificate is trustworthy. This works because the WWW class seems to simply use the default trust manager. More about the Android side of this topic: https://developer.android.com/training/articles/security-ssl.html
The problem is solvable by using a selfmade android plugin for Unity. The following code is from my Java plugin code. It contains a class with a static method which gets from unity the certificate and adds it to a list of allowed certificates. It has to be called once before the first use of WWW.
public class JavaSSLHelper
{
//see https://developer.android.com/training/articles/security-ssl.html
public static void trust(byte[] crtFileContent)
{
try
{
// Load CAs from an InputStream
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new ByteArrayInputStream(crtFileContent));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.d("JavaSSLHelper", "ca=" + ((X509Certificate) ca).getSubjectDN());
Log.d("JavaSSLHelper", "Certificate successfully created");
} finally
{
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
try
{
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
//this is important: unity will use the default ssl socket factory we just created
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
Log.d("JavaSSLHelper", "Default SSL Socket set.");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (KeyManagementException e) {
throw new RuntimeException(e);
}
}catch(Exception e)
{
throw new RuntimeException(e);
}
}
}
Then in Unity you just have to call this method giving the certificate down to android:
string cert = @""; //<-- include your CRT file as string
AndroidJavaClass clsJavaSSLHelper = new AndroidJavaClass("your.package.name.JavaSSLHelper");
byte[] certBytes = System.Text.Encoding.ASCII.GetBytes(cert);
clsJavaSSLHelper.CallStatic("trust", certBytes); //here we call the trust method from above
After this call WWW should simply do its job.
Because of requests I added the described plugin as a download in my blog here
Hey DevLuz, 3 years later.
I downloaded your plugin for c#, an UnityPackage named AndroidHttpsHelper... and is not working, I'm a novice programmer focused more on animations and interfaces, not really a network guy but there's no one else that can do this cuz no one knows Unity, can you help me with this?
Your answer
Follow this Question
Related Questions
WWW with HTTPS on Android not working 0 Answers
www not working on android and iOS 0 Answers
HTTPS + Android (sha2 certificate) 0 Answers
WWW and SSL on Android 1 Answer