Force TLS 1.2 on appengine dev server SDK

社会主义新天地 提交于 2019-12-11 06:56:36

问题


This is similar to this question: Force TLS > 1.0 on AppEngine local development server in Java except that the answer doesn't work because it assumes a static SDK location(?).

I have a Google App Engine application that uses a third party payment library (braintree) that communicates over HTTPS using TLSv1.2. However, whenever the braintree library makes calls to the braintree sandbox environment the resulting urlfetch always gives the following error:

Caused by: javax.net.ssl.SSLHandshakeException: Could not verify SSL certificate for URL: https://api.sandbox.braintreegateway.com:443/merchants/**********/client_token
    at com.google.appengine.api.urlfetch.URLFetchServiceImpl.convertApplicationException(URLFetchServiceImpl.java:174)
    at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:43)
    at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.fetchResponse(URLFetchServiceStreamHandler.java:543)
    at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getInputStream(URLFetchServiceStreamHandler.java:422)
    at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getResponseCode(URLFetchServiceStreamHandler.java:275)
    at com.braintreegateway.util.Http.httpRequest(Http.java:120)

Whilst this error only happens on the App Engine development server (and not when deployed into App Engine land), it still means that I can't test the stuff I need to in development.

According to this: https://groups.google.com/forum/#!topic/google-appengine-stackoverflow/tdr4T1CJRn8 the problem is that App Engine isn't using TLSv1.2.

My application is an App Engine app (Standard Environment) using the SDK version 1.9.26.

The appengine section of my gradle configuration looks like so:

appengine {
    httpAddress = "0.0.0.0"
    httpPort = 8888
    downloadSdk = false

    appcfg {
        update {
            useJava7 = true
        }

        jvmFlags = ['-Ddatastore.backing_store=../../src/main/webapp/WEB-INF/appengine-generated/local_db.bin',
                    // Desperation:
                    '-Ddeployment.security.TLSv1.0=false',
                    '-Ddeployment.security.TLSv1.1=false',
                    '-Ddeployment.security.TLSv1.2=true',
                    '-Dhttps.protocols=TLSv1.2',
                    '-Dappengine.fullscan.seconds=5',
                    '-Xdebug',
                    '-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8889',
                    '-XX:MaxPermSize=512m']
        oauth2 = true
        extraOptions = appCfgOpts
    }

    enhancer {
        api = "jdo"
        version = "v1"
        enhanceOnBuild = true
    }

}

I have tried updating the dev_appserver.sh in my local appengine-sdk directory to read:

exec "${RUN_JAVA}" "${SCRIPT_NAME}" \
    -Dhttps.protocols=TLSv1.2 -Ddeployment.security.TLSv1.0=false -Ddeployment.security.TLSv1.1=false -Ddeployment.security.TLSv1.2=true -ea -cp "${JAR_FILE}" \
    com.google.appengine.tools.KickStart \
    com.google.appengine.tools.development.DevAppServerMain "$@"

and setting downloadSdk = false and setting the appengine.sdk.root so that the gradle appengineRun task actually uses it.

I cannot use Java 8. I have also tried putting this in my code: System.setProperty("https.protocols", "TLSv1.2");

None of this works. Either I'm barking up the wrong tree, and trying all the wrong things, or I'm doing something wrong.

How can I get this to work?

Update:

It looks like the problem is actually that the sslSocketFactory is never created, because urlfetch will never return an HttpsURLConnection (App Engine URLfetch to validate self-signed certificate)

Still searching for a resolution.


回答1:


To fix this I had to run the project locally under the Java 8 SDK. Even though Java 8 isn't supported on App Engine yet, at least I can make Braintree sandbox payments in development and actually test my workflow.

I can then rely on the build server to check it still builds under Java 7.

To do this in IntelliJ:

+; to bring up Project Settings, then change the Project SDK to Java 1.8:

+, to bring up Preferences, then change the Gradle JVM option to Use Project JDK:

Then run gradle clean build. Then run the appengineRun gradle task to start up the dev system and all should be fine.

As mentioned in the second answer here: Force TLS > 1.0 on AppEngine local development server in Java Java 8 uses TLSv1.8 by default.

Even though it feels totally wrong developing and testing your app on a JRE other than the one it will actually be run on, needs must. :(



来源:https://stackoverflow.com/questions/43919057/force-tls-1-2-on-appengine-dev-server-sdk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!