Oracle BPEL (Java 8U92) 使用 HTTPS 调用 REST 服务时出现 SSL 握手异常

Oracle BPEL (Java 8U92) invoking REST service using HTTPS gives SSL Handshake Exception

我已经使用 oracle SOA 12c 设置了一个基本的 weblogic 域,用于开发一个可以调用苹果 APN 服务的组合。 Apple APN 需要使用 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 和 TLS 1.2 加密的 HTTP2 连接。

JKS 信任库已配置并加载了根证书、中间证书和服务器证书。

geotrustrootca, Jun 21, 2016, trustedCertEntry, 
Certificate fingerprint (SHA1): DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12
serverc_ss_cert, Jun 21, 2016, trustedCertEntry, 
Certificate fingerprint (SHA1): 73:C4:A9:4E:E8:1B:14:58:7B:64:47:02:73:01:15:3E:88:E8:E8:66
appledevpush, Jun 21, 2016, trustedCertEntry, 
Certificate fingerprint (SHA1): CC:18:A5:75:04:74:3A:3B:72:D7:A5:07:F2:CD:E4:83:51:11:34:CB
appleintermediate, Jun 21, 2016, trustedCertEntry, 
Certificate fingerprint (SHA1): 8E:83:21:CA:08:B0:8E:37:26:FE:1D:82:99:68:84:EE:B5:F0:D6:55

已通过添加 java 属性 -Djavax.net.ssl.trustStore=/u01/data/keystores/truststore.jks

更改了 setDomainEnv.sh

当测试一个简单的 BPEL 组合时,如果失败并出现 SSLHandshakeException,则对 Apple 的 APN 服务进行 REST 调用:

[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', SEND TLSv1.2 ALERT:  fatal, description = certificate_unknown
[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', WRITE: TLSv1.2 Alert, length = 2
[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', called closeSocket()
[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

在调试 SSL 协商时看到;

%% No cached client session
*** ClientHello, TLSv1.2

....

*** ServerHello, TLSv1.2
RandomCookie:  GMT: 1922117017 bytes = { 236, 133, 59, 43, 182, 3, 165, 71, 241, 54, 240, 145, 222, 41, 200, 242, 63, 237, 253, 77, 188, 235, 187, 177, 245, 173, 53, 232 }
Session ID:  {119, 250, 96, 4, 116, 33, 211, 17, 47, 213, 227, 158, 164, 107, 14, 73, 157, 194, 0, 104, 54, 237, 0, 58, 229, 225, 158, 2, 29, 159, 79, 171}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

...

%% Initialized:  [Session-7, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384]
** TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', READ: TLSv1.2 Handshake, length = 2576
*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: C=US, ST=California, O=Apple Inc., OU=management:idms.group.533599, CN=api.development.push.apple.com
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

...

chain [1] = [
[
  Version: V3
  Subject: C=US, O=Apple Inc., OU=Certification Authority, CN=Apple IST CA 2 - G1
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

...

***
%% Invalidated:  [Session-7, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384]
[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', SEND TLSv1.2 ALERT:  fatal, description = certificate_unknown
[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', WRITE: TLSv1.2 Alert, length = 2
[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', called closeSocket()
[ACTIVE] ExecuteThread: '58' for queue: 'weblogic.kernel.Default (self-tuning)', handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

我的结论是服务器 N=api.development.push.apple.com 的服务器证书被接受但中间 CA CN=Apple IST CA 2 - G1 的证书被拒绝。

CN=Apple IST CA 2 - G1的发行者是CN=GeoTrust Global CA, O=GeoTrust Inc., C=US,序列号023a74。此证书也加载到信任库中;

别名:geotrustrootca 创建日期:2016-06-21 条目类型:trustedCertEntry

Owner: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Issuer: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Serial number: 23456
Valid from: Tue May 21 06:00:00 CEST 2002 until: Sat May 21 06:00:00 CEST 2022
Certificate fingerprints:
     MD5:  F7:75:AB:29:FB:51:4E:B7:77:5E:FF:05:3C:99:8E:F5
     SHA1: DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12
     SHA256: FF:85:6A:2D:25:1D:CD:88:D3:66:56:F4:50:12:67:98:CF:AB:AA:DE:40:79:9C:72:2D:E4:D2:B5:DB:36:A7:3A
     Signature algorithm name: SHA1withRSA
     Version: 3

任何想法(如果我的结论是正确的)为什么中间证书被拒绝或如何进一步调试?使用浏览器打开 APN 的 URI 并检查证书时,我得到的结果与信任库中的相同。

== 更新 1 ==

尝试使用 curl 连接。 首先将证书从信任库导出到 /u01/data/keystores

$keytool -keystore truststore.jks -exportcert -alias geotrustrootca | openssl x509 -inform der -text > geotrustrootca.pem
 $keytool -keystore truststore.jks -exportcert -alias appledevpush | openssl x509 -inform der -text > appledevpush.pem
$keytool -keystore truststore.jks -exportcert -alias appleintermediate | openssl x509 -inform der -text > appleintermediate.pem

然后尝试使用 curl

进行连接
$ curl --capath /u01/data/keystores --verbose  https://api.development.push.apple.com/3/device/
* About to connect() to api.development.push.apple.com port 443 (#0)
*   Trying 17.172.238.203... connected
* Connected to api.development.push.apple.com (17.172.238.203) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* failed to load '/u01/data/keystores/identitykeystore.jks' from CURLOPT_CAPATH
* failed to load '/u01/data/keystores/appledevpush.cer' from CURLOPT_CAPATH
* failed to load '/u01/data/keystores/geotrustrootca.cer' from CURLOPT_CAPATH
* failed to load '/u01/data/keystores/truststore.jks' from CURLOPT_CAPATH
* failed to load '/u01/data/keystores/yum-oracle-8v1ncO' from CURLOPT_CAPATH
* failed to load '/u01/data/keystores/vm0010.localdomain-rootCA.der' from CURLOPT_CAPATH
* failed to load '/u01/data/keystores/appleintermediate.cer' from CURLOPT_CAPATH
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: /u01/data/keystores
* NSS: client certificate not found (nickname not specified)
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*   subject: C=US,ST=California,O=Apple Inc.,OU=management:idms.group.533599,CN=api.development.push.apple.com
*   start date: Jun 19 01:49:43 2015 GMT
*   expire date: Jul 18 01:49:43 2017 GMT
*   common name: api.development.push.apple.com
*   issuer: C=US,O=Apple Inc.,OU=Certification Authority,CN=Apple IST CA 2 - G1
> GET /3/device/ HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: api.development.push.apple.com
> Accept: */*
> 
* Connection #0 to host api.development.push.apple.com left intact
* Closing connection #0
@@�HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 474554202f332f6465766963652f20485454502f312e310d

所以证书是正确的。

== 更新 2 ==

再次重新创建信任库。通过在 netscape 中打开 url https://api.development.push.apple.com/3/device/ 并以 pem 格式保存证书来获取 pem 文件。

在新的 truststore.jks

中导入了证书

用于 ls -1 *.der 中的文件;做 keytool -importcert -keystore truststore.jks -file $file -storepass welcome1 -noprompt -alias $file ;完成

没有快乐...

== 更新 3 ==

现在在 server.out 中观察到重新启动托管服务器时,默认的自签名证书也已加载。

<Jul 11, 2016 10:15:50 PM CEST> <Warning> <oracle.soa.healthcheck> <BEA-000000> <On startup, health check id 881 failed for category 'Startup'. Ran 6 checks. Number of failures=1, errors=1, warnings=0.>
adding as trusted cert:
  Subject: CN=CertGenCA, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
  Issuer:  CN=CertGenCA, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
  Algorithm: RSA; Serial number: 0x40044886c441ef3b643a8066409afca0
  Valid from Sat Dec 01 04:07:51 CET 2012 until Thu Dec 02 04:07:51 CET 2032

adding as trusted cert:
  Subject: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
  Issuer:  CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
  Algorithm: RSA; Serial number: 0x234b5559d1fa0f3ff5c82bdfed032a87
  Valid from Thu Oct 24 17:54:45 CEST 2002 until Tue Oct 25 17:54:45 CEST 2022

javax.net.ssl.trustStore 设置为自定义信任库。同样在 weblogic 中,Identity 和 Truststore 位置已设置为自定义 JKS 存储。

即使从 $WLS_HOME/lib 中删除 DemoTrust.jks 后,证书仍会添加为受信任的证书。我目前不知道这些是从哪里来的。

== 更新 4 ==

$DOMAIN_HOME/security 包含 DemoIdentity.jks。删除此文件并重新启动托管服务器后,不再加载演示受信任的证书。

== 更新 5 ==

根据目标 url SAS SSL/TLS 诊断工具验证了信任库。确保信任库设置正确。

正如 user2351802 所指出的,必须使用 OPSS 密钥库而不是 Java 属性 javax.net.ssl.trustStore.

中定义的 JKS 密钥库

在 SOA Suite 10g/11g 中,使用单向 SSL 从组合调用外部 Web 服务时的标准安全传输方式是创建 JKS 信任库并在 javax.net.ssl.trustStore [=104] 中指定该信任库的位置=] 属性。 SOA Suite 12.2.1.1 Admin Guide to use the JKS truststore for maken one-way SSL connections from SOA composites. The Oracle WebLogic Server 12.2.1.1.0 Admin Guide mentions the (new) OPSS Keystore and refers to the document "Securing Applications with Oracle Platform Security Services" 中甚至还记录了使用和配置新的 KSS OPSS 密钥库的信息。尽管它提到了为 LDAP 显式设置单向 SSL 的过程,但它似乎是 FMW 应用程序的新常用方法。

在清理 weblogic 中的身份和信任库并仅将服务器证书添加到身份库后(因此 JKS 信任库中不再有受信任的证书)并将根证书添加到 OPSS system/trust 它起作用了!

好的。这听起来很奇怪,但它会起作用。我们有相同的 SOA 12c 设置,但我们使用标准 Java 托管 SOA 服务器的信任密钥库。

我看到您已修改 setDomainEnv.sh 以指定 /u01/data/keystores/truststore.jks 作为您的密钥库。

理论上,如果根证书在我的情况下存在于 cacerts 中,而在您的情况下 truststore.jks 它应该可以工作。我可以确认 SOAP 服务与密钥库一起正常工作。

由于证书错误,通过 REST 适配器调用 REST 服务失败,与您的情况相同。

Here's what made it to work:
Login to EM
Weblogic Domain -> Security -> Keystore
Select System (stripe) -> trust -> Hit the manage button
Here import the root cert of geotrustrootca.

反弹 SOA 服务器。测试您的服务。它应该可以正常工作。

What I dont understand is: System (stripe) -> trust = This is preconfigured as a demo trust store when you configure a domain. I have already change the keystore setting for managed server to use cacerts. Somehow it looks like this kss trust store is still referenced somewhere. The question is where?

一定要分享,以防万一你弄明白了。与此同时,该解决方案将助您一臂之力。