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?

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: Security with network protocols  |  Android Developers

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.