16

I have a problem when I want to connect with Paypal Rest API with POST method. When I am not using modernhttpclient I got error

The authentication or decryption has failed. 

But when I am using modernhttpclient it work in Android API 23 (Marshmallow) and when I test in Android API 19 (device) and Android API 16 (emulator) I got error

ex {Javax.Net.Ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=…} Javax.Net.Ssl.SSLHandshakeException

According to ssl handshake exception android I need to use custom socket factory. But how can I implement it in HttpClient or modernHttpClient?

Community
  • 1
  • 1
albilaga
  • 419
  • 1
  • 10
  • 26
  • What version of `Xamarin.Android` are you currently using? – SushiHangover May 19 '16 at 03:35
  • Xamarin.Android Version: 6.1.0.56 (Xamarin Business) – albilaga May 19 '16 at 07:53
  • Ok, we are using the Alpha 6.1.99.xxx and have a similar (but different ;-) issue and have resorted to using the "native" Java API, i.e. `HttpURLConnection` to do our posts due to `HttpClient` problems with postings a `Stream` and getting a Java IO end of stream problem. Skipping the .Net framework solved it for us. – SushiHangover May 19 '16 at 08:02
  • So I need to change using HttpURLConnection instead HttpClient from .Net framework? Will try it later – albilaga May 19 '16 at 08:49
  • It was not a "trivial" change as HttpURLConnection is from the Java framework and thus not a drop in replacement, but for us, skipping the .Net/Mono framework and using only Java framework got us around the "issue" (still not sure just what the issue is... .Net to Java bridge, just a bug in Xamarin with them pulling in internal usage of Java stream, ... ) Something is just wrong in the content length that is being posted vs the actual length of the content... – SushiHangover May 19 '16 at 09:02
  • Yeah I agree. Thats why I ask here if anybody has done it using HttpClient because change it to Java framework is not a trivial thing and will wasting some time – albilaga May 19 '16 at 09:33

5 Answers5

9

Not sure if I can fully answer your question, but I'll give it a try:

If you analyze the Paypal REST API endpoint, for example with SSL Labs like so https://www.ssllabs.com/ssltest/analyze.html?d=api.sandbox.paypal.com&hideResults=on, you see they only support the TLS 1.2 protocol.

Now Android does support this since API Level 16, as you can see here https://developer.android.com/reference/javax/net/ssl/SSLSocket.html, but it is disabled by default and only in API Levels 20+ they enabled it.

In the Xamarin forums someone posted a solution for enabling TLS 1.2 for Android with API Levels 16 to 19 by forking ModernHttpClient and adding an improved SSL socket factory: https://forums.xamarin.com/discussion/63005/modernhttpclient-tls-1-2-android-api-19

This should fix your issue with those Android versions, but it will not help you with versions before Android 4.1.

Florian Haider
  • 1,892
  • 18
  • 23
3

This was due to a few reasons:

  1. There is a lack of clarity surrounding TLS 1.2 support on older Android devices.
  2. Device manufacturers have differing commitments to the official Android specs for shipping TLS 1.2 on their devices
  3. Carriers and device manufacturers have differing commitments to providing software and security updates to their customers.

you can force TLS v1.2 for Android 4.0 devices that don't have it enabled by default

To fix it use the following code as async call.

    ProviderInstaller.installIfNeededAsync(getApplicationContext(), new 
    ProviderInstaller.ProviderInstallListener() {
                @Override
                public void onProviderInstalled() {
                    SSLContext sslContext;
                    try {
                        sslContext = SSLContext.getInstance("TLSv1.2");
                        sslContext.init(null, null, null);
                        sslContext.createSSLEngine();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onProviderInstallFailed(int i, Intent intent) {

                }
            });

For more info use this reference

https://ankushg.com/posts/tls-1.2-on-android/

mani
  • 709
  • 6
  • 13
1

You can use the ProviderInstaller from Google Play Services, it replaces the system SSL provider with a more recent one provided by Google:

https://developer.android.com/training/articles/security-gms-provider.html

I initialize it in the onCreate() of my application and that error is gone. I am sure you can do that from Xamarin somehow.

stephane k.
  • 1,668
  • 20
  • 21
0

Basically this issue comes when SSL at server side have a broken chain, server need to include the complete the chain and include the intermediate Root chain,

for more Info please have a refer to this link.

https://developer.android.com/training/articles/security-ssl.html

Nitin Jain
  • 1,314
  • 11
  • 15
0

if you use Picasso library, update that to last version the last version now is : implementation 'com.squareup.picasso:picasso:2.71828' just it