英文:
How to properly create an SSLSocketFactory for 2 way TLS? (For ApplePay)
问题
以下是您提供的内容的翻译部分:
我正在尝试使用Java向ApplePay发出请求,但无法成功。
以下是curl请求:
$ curl -X POST --cert-type P12 --cert cert.p12 https://apple-pay-gateway-pr-pod1.apple.com/paymentservices/startSession -d '{}'
{
"statusMessage": "Payment Services Exception Invalid session request",
"statusCode": "400"
}
这在一定程度上是正常的,因为它能够与苹果服务器通信。
以下是我生成新的Feign客户端SSLContextFactory的代码(使用Kotlin编写):
@Bean
fun client(): Client { // 一个Feign客户端
val keystoreFile = File("/path/to/cert.p12")
val keyStore = KeyStore.getInstance("PKCS12")
keyStore.load(keystoreFile.inputStream(), null)
val keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
keyFactory.init(keyStore, null)
val trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm()
)
trustManagerFactory.init(keyStore)
val trustManagers = trustManagerFactory.trustManagers
val trustManager = trustManagers[0] as X509TrustManager
val sslContext: SSLContext = SSLContext.getInstance("TLS")
sslContext.init(keyFactory.keyManagers, trustManagers, null)
return feign.okhttp.OkHttpClient(
FeignConfiguration.enrichOkHttpClientBuilder(logbook)
.sslSocketFactory(sslContext.socketFactory, trustManager)
.connectionSpecs(
arrayListOf(
ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256
)
.build()
)
)
.build()
)
}
但是,当我尝试向相同的URL发出请求时,我收到以下错误:
feign.RetryableException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty executing POST https://apple-pay-gateway-pr-pod1.apple.com/paymentservices/startSession/paymentSession
有人知道我可能做错了什么吗?
英文:
I'm trying to make a request to ApplePay but am not able to do it with Java.
Here's the curl request:
$ curl -X POST --cert-type P12 --cert cert.p12 https://apple-pay-gateway-pr-pod1.apple.com/paymentservices/startSession -d '{}'
{
"statusMessage": "Payment Services Exception Invalid session request",
"statusCode": "400"
}
which is normal to the extent that it's able to communicate with the apple server.
Here's my code to generate a new Feign client SSLContextFactory (written in Kotlin):
@Bean
fun client(): Client { // a Feign Client
val keystoreFile = File("/path/to/cert.p12")
val keyStore = KeyStore.getInstance("PKCS12")
keyStore.load(keystoreFile.inputStream(), null)
val keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, null)
val trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm()
)
trustManagerFactory.init(keyStore)
val trustManagers = trustManagerFactory.trustManagers
val trustManager = trustManagers[0] as X509TrustManager
val sslContext: SSLContext = SSLContext.getInstance("TLS")
sslContext.init(keyFactory.keyManagers, trustManagers, null)
return feign.okhttp.OkHttpClient(
FeignConfiguration.enrichOkHttpClientBuilder(logbook)
.sslSocketFactory(sslContext.socketFactory, trustManager)
.connectionSpecs(
arrayListOf(
ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
, CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
, CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256
, CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256
)
.build()
)
)
.build()
)
}
But when I try to make a request to the same URL, I get the following error:
feign.RetryableException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty executing POST https://apple-pay-gateway-pr-pod1.apple.com/paymentservices/startSession/paymentSession
Anyone have an idea of what I may be doing wrong?
答案1
得分: 1
以下是翻译好的部分:
我的技术负责人能够帮助解决这个问题,但 @dave_thompson_085 的答案也应该有所帮助。
所以,我基本上将 feign 客户端部分之前的代码替换为:
val keystoreStream = <stream>;
val keyStore = KeyStore.getInstance("PKCS12")
keyStore.load(keystoreStream, keystorePassword.toCharArray())
val sslContext: SSLContext = SSLContexts.custom()
.loadTrustMaterial(null, TrustSelfSignedStrategy())
.loadKeyMaterial(keyStore, keystorePassword.toCharArray())
.build()
val tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm())
tmf.init(keyStore) // 可以使用 tmf 获取单独的 TrustManager
英文:
My tech lead was able to help resolve this, but @dave_thompson_085 's answer should also help.
So I basically replaced the parts before the feign client stuff with:
val keystoreStream = <stream>
val keyStore = KeyStore.getInstance("PKCS12")
keyStore.load(keystoreStream, keystorePassword.toCharArray())
val sslContext: SSLContext = SSLContexts.custom()
.loadTrustMaterial(null, TrustSelfSignedStrategy())
.loadKeyMaterial(keyStore, keystorePassword.toCharArray())
.build()
val tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm())
tmf.init(keyStore) // can use tmf to get individual trustmanager
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论