I am trying to implement DynamoDBMapper from AWS but the application crashes when I try to connect to the AWS servers.
To start, I am running Android 4.4.2 on an Android Studio emulator and everything seems to be working fine. No problems there. Nonetheless, when I try to run on an actual device (running 4.4.2 on a Tablet... don't know the manufacturer), I get the following error:
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)
Here is the full stack trace:
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
Followed by:
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
And here is my sourcecode:
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);
It is that last line of code where the error begins.
Now, I have looked around on SO and a few search engines and have learned that some Android devices fall back to SSL v3, while the server I am trying to connect to uses TLS v1.0 (went to www.ssllabs.com and found out that it does use TLS 1.0). Here is another SO question where someone seems to have solved an issue very similiar to this:
How to disable SSLv3 in android for HttpsUrlConnection?
Thus, if this is what is causing the issue (SSLv3 needing to be removed), how can I go about configuring the AmazonDynamoDbClient to use only TLS 1.0? I noticed you can create a ClientConfiguration and use:
clientConfiguration.getApacheHttpClientConfig().setSslSocketFactory(NoSSLv3SocketFactory);
and supply it with the awsCredentials in the AmazonDynamoDbClient constructor. But, it accepts:
org.apache.http.conn.ssl.SSLSocketFactory
not
javax.net.ssl.SSLSocketFactory
which is what is used in the answer from the link I provided (not to mention Android Studio is informing me that org.apache.http.conn.ssl.SSLSocketFactory is deprecated).
At any rate, any help with this matter would be much appreciated. Thanks!
You can use org.apache.http.conn.ssl.SSLConnectionSocketFactory instead of org.apache.http.conn.ssl.SSLSocketFactory.
From the JavaDoc of SSLSocketFactory (https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLSocketFactory.html) -
Deprecated.
(4.3) use SSLConnectionSocketFactory
Some services like Cognito support TLSv1.0+, while some say DynamoDB supports only TLSv1.0 (not above). If your device supports TLSv1.0, it should work then. Since you said the code works on emulator but not on the tablet, it's hard to say where the problem is. I suggest you try these:
Visit https://dynamodb.us-west-2.amazonaws.com in your browser. If your device can handle TLSv1.0, you should see healthy: dynamodb.us-west-2.amazonaws.com.
Run the same code on a different device.
Some notes from comments:
SSLv3 has been deprecated on all AWS services.
Remove aws-java-sdk and use aws-android-sdk. The latter has lots of optimizations for Android.
aws-android-sdk uses HttpURLConnection as the default HTTP library.
To test what protocols a service supports, use this command:
openssl s_client -connect dynamodb.us-west-2.amazonaws.com:443
Related
While using Okhttp3 to request(get and post) HTTPS urls from Dataflow jobs, the program is throwing SSL handshake Exception and failing. Exact message is "javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure"
The same code was working earlier like 3-4 weeks(Before Nov-23) back in Dataflow. Now it's failing with the above exception. Will this be an issue arrise because of some changes in the server (HTTPS URL provider) ? Or is it something to do with the my dataflow/beam setup.
SDK and lib versions -
Apache Beam SDK for Java 2.16.0
com.squareup.okhttp3:okhttp:4.2.2
Looks like a change in the SSL configuration of your server. Try this site to confirm your server and device are compatible.
https://www.ssllabs.com/ssltest/
Like I explain in my answer here, GCP disables GCM algos by default, and most probably your server only supports GCM and POLY.
To re-enable GCM in the pipeline, you need to register a JvmInitializer and change the security settings.
Please look at my other answer on how to do this.
I am getting the following error when trying to connect to IBM's Watson API:
java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.ibm.watson.developer_cloud.service.security.IamTokenManager.callIamApi(IamTokenManager.java:190)
at com.ibm.watson.developer_cloud.service.security.IamTokenManager.requestToken(IamTokenManager.java:108)
at com.ibm.watson.developer_cloud.service.security.IamTokenManager.getToken(IamTokenManager.java:78)
at com.ibm.watson.developer_cloud.service.WatsonService.setAuthentication(WatsonService.java:375)
at com.ibm.watson.developer_cloud.service.WatsonService.createCall(WatsonService.java:206)
at com.ibm.watson.developer_cloud.service.WatsonService.createServiceCall(WatsonService.java:240)
at com.ibm.watson.developer_cloud.assistant.v2.Assistant.createSession(Assistant.java:107)
[...]
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:279)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1152)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1063)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:318)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:282)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:167)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
[...]
This is the Java code which tries to initiate the API call:
// Init assistant
IamOptions imaOptions = new IamOptions.Builder()
.apiKey(API_KEY)
.build();
assistant = new Assistant("2019-03-13", imaOptions);
assistant.setEndPoint(END_POINT_FRA);
// Create session
CreateSessionOptions options = new CreateSessionOptions.Builder(ASSISTANT_ID).build();
ServiceCall<SessionResponse> session = assistant.createSession(options);
The exception is thrown in the last line. Interestingly, I am able to connect perfectly fine when I run this through a stand-alone unit test. It is only when I try to connect from a server application that I get this SSL error.
I have already tried the following:
import all required SSL certificates into the applications's
truststore
set system property to support TLS 1.2 prior to TLS 1.1
verified that JCE full policy files are installed (as part of Java 11,
which is the version I am on)
used nmap to verify the server's cipher suites and check that they are supported by the JDK ( nmap -sV --script ssl-enum-ciphers -p 443 wildcard.bluemix.net )
I have also read through and followed these here articles:
Received fatal alert: handshake_failure through SSLHandshakeException
https://confluence.atlassian.com/jirakb/sslhandshakeexception-received-fatal-alert-handshake_failure-due-to-no-overlap-in-cipher-suite-943544397.html
I am a bit lost now. Any ideas what might be cuasing the SSL handshake problem or how I could diagnose it further?
==== Update ====
After digging around this topic, I think I have managed to isolate it. It seems to be an actual bug in Java 11.0.1, which is also still present in 11.0.2. Root cause is that Java 11 (OpenJDK) does not play nice with TLSv1.3, as described here: https://webtide.com/openjdk-11-and-tls-1-3-issues/ and in a bug report here https://bugs.openjdk.java.net/browse/JDK-8213202
Now the issue is how to disable TLSv1.3. I have already tried the solutions provided here https://blogs.oracle.com/java-platform-group/jdk-8-will-use-tls-12-as-default and here https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html (protocols and properties), but for some reason this disabling does not take effect in my case. My code is using the org.apache.http.impl.client.ClosableHttpClient and the Builder does not allow me access to the underlying SSLConnectionSocketFactory (where I might be able to disable TLSv1.3). So, the question remains: How can I disable TLSv1.3 in this particular setting?
(PS: The problem also occures when trying to access the Google NL and Vision APIs - language.googleapis.com and vision.googleapis.com)
There is a bug in JDK 11.0.1 and 11.0.2 related to TLSv1.3. This version of the TLS protocol needs to be disabled by setting the following system property:
-Djdk.tls.client.protocols=TLSv1.1,TLSv1.2
Presumably, this bug will be fixed with the release of JDK 11.0.3., which is due mid-April '19.
I am getting below exception while firing simple http GET request from java.(actually from jsoup java api).
javax.net.ssl.SSLKeyException: Invalid signature on ECDH server key exchange message
at sun.security.ssl.HandshakeMessage$ECDH_ServerKeyExchange.<init>(HandshakeMessage.java:1098)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:278)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:913)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:849)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1035)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1344)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:512)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:493)
at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:205)
at org.jsoup.helper.HttpConnection.get(HttpConnection.java:194)
at com.ampower.scraper.data.util.DocumentUtil.test(DocumentUtil.java:205)
at com.ampower.scraper.goolesearch.email.EmailScraper.doGoogleSearch(EmailScraper.java:87)
at com.ampower.scraper.goolesearch.email.EmailScraper.main(EmailScraper.java:50)
Here iam using java version is 1.7.0_101. please suggest.
It could be a expired certificate problem. I stumbled upon the same error; after debugging the SSL/TLS Connections I noticed said certicate was no longer valid anymore:
Validaty: [From: date-in-the-past,
To: date-in-the-past]
As soon as the certicate was renewed, the error was gone.
Try one of the following options:
Option 1: JDK upgrade
If possible, change your JDK version for a newer version and check if you run into the same issue again.
Option 2: Possible known issue
A similar issue has been reported. The solution comes from the using of the jdk.tls.client.protocols system property.
Option 3: Disable TLS certificates validation
Jsoup.connect(url).validateTLSCertificates(false).get();
Option 4: Debug the SSL exchange
Paste the url of your target site here: Comodoca's SSL analyzer
See the full detailed approach in this SO answer (Wht not Java7?).
See also:
Android Jsoup certificate issues
getting javax.net.ssl.SSLException: Received fatal alert: protocol_version while scraping data using Jsoup
HttpConnection#validateTLSCertificates
This project located here was completed with SSL. Now I need to do to this without SSL. I want to design it for a desktop (html5, websocket).
Currently I am getting this error type : http://www.guj.com.br/java/261352-reconfigurar-ssl-default-java in the android app...
Before this error explain that this type took two lines:
httpsurlconnection.setSSLSocketFactory(GarageSSLSocketFactory.getSSLSocketFactory(application));
and I had this error:
"Javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x74f61128: Failure in SSL library, usually a protocol erro erro:140770FCSSL routines:SS23_GET_SERVER_HELLO:unknown protocol(external/openssl/ssl/s23_clnt.c:7660x7449ad5c:0x0000000)"
Now I'm getting the error:
can not be cast to com.android.okhttp.internal.http.HttpURLConnectionImpl javax.net.ssl.HttpsURLConnection
What should I do?
You still have some SSL code left.
A HttpsURLConnection where you need to get rid of that s so it becomes a regular HttpURLConnection.
I have a webapp that sends a SOAP request to a 3rd party server. When the request is made on my local computer it works without a problem, but when I deploy my application to my server I get an error with the following causes:
com.sun.xml.messaging.saaj.SOAPExceptionImpl: java.security.PrivilegedActionException: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Message send failed
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: algorithm check failed: MD2withRSA is disabled
I've searched around but I can't find anything relevant to my situation. It's probably worth noting that the request I'm making is to an https url. My computer is running Windows XP and the server is running Slackware Linux. Any ideas what might be causing the server to reject the request?
Check your Java versions on your local machine, and your server.
From here, it seems the jvm 6u17 disabled MD2 as it is insecure, and whatever you connect to is using MD2
MD2withRSA is highly vulnerable and therefore deactivated in Sun... aeh Oracle's JVM. You should ask the owner of the remote service, whether his server supports more secure encryption methods (I think, older Apache HTTPd versions do offer MD2withRSA by default...). In order to resolve this problem without forcing the provider to change the method, you may use your own implementation of the X509TrustManager that accepts the old method.
A Google search on "MD2withRSA" showed this URL as the first hit, that seems to point to a change in a certain Java version. Probably the verasiuons on your local computer and the server do not match.
Newer Java 7 (version 1.7) allows re-enabling MD2 via $JAVA_HOME/jre/lib/security/java.security file. Download and install Java 7 and modify java.security file in text editor as follows
1) Remove MD2 from following property
jdk.certpath.disabledAlgorithms= # MD2
2) Ensure following property is commented out
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
3) Restart java application
Warning: MD2 is disabled by default in Jdk 7 because it is insecure. However, it can be enabled as described above to support older deployments.