Ошибка AWS DynamoDbMapper... Причина: javax.net.ssl.SSLProtocolException:

Я пытаюсь реализовать DynamoDBMapper из AWS, но происходит сбой приложения, когда я пытаюсь подключиться к серверам AWS.

Для начала я использую Android 4.4.2 на эмуляторе Android Studio, и все, кажется, работает нормально. Там нет проблем. Тем не менее, когда я пытаюсь запустить на реальном устройстве (работающем 4.4.2 на планшете... не знаю производителя), я получаю следующую ошибку:

Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6bffcdf0: 
     Failure in SSL library, usually a protocol error error:140740B5:SSL 
     routines:SSL23_CLIENT_HELLO:no ciphers available (external/openssl/ssl/s23_clnt.c:486 0x68474ce0:0x00000000)

Вот полная трассировка стека:

Caused by: com.amazonaws.AmazonClientException: Unable to execute HTTP request: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6bffcdf0: Failure in SSL library, usually a protocol error error:140740B5:SSL routines:SSL23_CLIENT_HELLO:no ciphers available (external/openssl/ssl/s23_clnt.c:486 0x68474ce0:0x00000000)

    com.amazonaws.http.AmazonHttpClient.executeHelper              AmazonHttpClient.java:421
    com.amazonaws.http.AmazonHttpClient.execute                    AmazonHttpClient.java:196
    com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke  AmazonDynamoDBClient.java:3257
    com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.getItem AmazonDynamoDBClient.java:904
    com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.load  DynamoDBMapper.java:393
    com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.load  DynamoDBMapper.java:466
    com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.load  DynamoDBMapper.java:340
    @@@@.@@@@@.@@@@$@@@@.doInBackground  MainActivity.java:1259
    @@@@.@@@@@.@@@@$@@@@.doInBackground  MainActivity.java:1237
    android.os.AsyncTask$2.call          AsyncTask.java:288
    java.util.concurrent.FutureTask.run  FutureTask.java:237
    ... 4 more

С последующим:

Caused by: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6bffcdf0: Failure in SSL library, usually a protocol error error:140740B5:SSL routines:SSL23_CLIENT_HELLO:no ciphers available (external/openssl/ssl/s23_clnt.c:486 0x68474ce0:0x00000000)

    com.android.org.conscrypt.NativeCrypto.SSL_do_handshake          Native Method
    com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake       OpenSSLSocketImpl.java:406
    com.android.okhttp.Connection.upgradeToTls                       Connection.java:146
    com.android.okhttp.Connection.connect                            Connection.java:107
    com.android.okhttp.internal.http.HttpEngine.connect              HttpEngine.java:294
    com.android.okhttp.internal.http.HttpEngine.sendSocketRequest    HttpEngine.java:255
    com.android.okhttp.internal.http.HttpEngine.sendRequest          HttpEngine.java:206
    com.android.okhttp.internal.http.HttpURLConnectionImpl.execute   HttpURLConnectionImpl.java:345
    com.android.okhttp.internal.http.HttpURLConnectionImpl.connect   HttpURLConnectionImpl.java:89
    com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream   HttpURLConnectionImpl.java:197
    com.android.okhttp.internal.http.HttpsURLConnectionImpl.getOutputStream  HttpsURLConnectionImpl.java:254
    com.amazonaws.http.UrlHttpClient.writeContentToConnection        UrlHttpClient.java:128
    com.amazonaws.http.UrlHttpClient.execute                         UrlHttpClient.java:65
    com.amazonaws.http.AmazonHttpClient.executeHelper                AmazonHttpClient.java:353
    ... 14 more

И вот мой исходный код:

BasicAWSCredentials awsCredentials = new BasicAWSCredentials("abcdef12345","blahblahblah");
AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient(awsCredentials);
DynamoDbMapper dbMapper = new DynamoDBMapper(dynamoDBClient);

//.... then eventually .....

AWSDriverNameTable awsDriverNameTable = dbMapper.load(AWSDriverNameTable.class, merchantID);

Это та последняя строка кода, где начинается ошибка.

Теперь я посмотрел на SO и несколько поисковых систем и узнал, что некоторые устройства Android используют SSL v3, а сервер, к которому я пытаюсь подключиться, использует TLS v1.0 (зашел на сайт www.ssllabs.com и нашел что он использует TLS 1.0). Вот еще один SO вопрос, где кто-то, кажется, решил проблему, очень похожую на эту:

Как отключить SSLv3 в Android для HttpsUrlConnection?

Таким образом, если это является причиной проблемы (необходимо удалить SSLv3), как я могу настроить AmazonDynamoDbClient для использования только TLS 1.0? Я заметил, что вы можете создать ClientConfiguration и использовать:

clientConfiguration.getApacheHttpClientConfig().setSslSocketFactory(NoSSLv3SocketFactory);

и предоставьте его с помощью awsCredentials в конструкторе AmazonDynamoDbClient. Но он принимает:

org.apache.http.conn.ssl.SSLSocketFactory

не

javax.net.ssl.SSLSocketFactory

именно это и используется в ответе по предоставленной мной ссылке (не говоря уже о том, что Android Studio сообщает мне, что org.apache.http.conn.ssl.SSLSocketFactory устарела).

Во всяком случае, любая помощь в этом вопросе будет высоко ценится. Спасибо!

2 ответа

Ты можешь использовать org.apache.http.conn.ssl.SSLConnectionSocketFactory вместо org.apache.http.conn.ssl.SSLSocketFactory,

Из JavaDoc SSLSocketFactory ( https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLSocketFactory.html) -

Устаревшее. (4.3) использовать SSLConnectionSocketFactory

Некоторые сервисы, такие как Cognito, поддерживают TLSv1.0+, в то время как некоторые говорят, что DynamoDB поддерживает только TLSv1.0 (не выше). Если ваше устройство поддерживает TLSv1.0, оно должно работать. Поскольку вы сказали, что код работает на эмуляторе, а не на планшете, трудно сказать, в чем проблема. Я предлагаю вам попробовать это:

  • Посетите https://dynamodb.us-west-2.amazonaws.com/ в вашем браузере. Если ваше устройство может обрабатывать TLSv1.0, вы должны увидеть healthy: dynamodb.us-west-2.amazonaws.com,
  • Запустите один и тот же код на другом устройстве.

Некоторые заметки из комментариев:

  • SSLv3 устарел во всех сервисах AWS.
  • Удалите aws-java-sdk и используйте aws-android-sdk. Последний имеет много оптимизаций для Android.
  • aws-android-sdk использует HttpURLConnection в качестве библиотеки HTTP по умолчанию.

Чтобы проверить, какие протоколы поддерживает служба, используйте эту команду:

openssl s_client -connect dynamodb.us-west-2.amazonaws.com:443
Другие вопросы по тегам