Gangmax Blog

解决Weblogic上HTTPS certificate keystores配置问题

由于我们的应用需要在weblogic上通过https实现双向certificate认证,所以必须要完成weblogic上的相关配置。

HTTPS two-way certificate authentication的基本原理是:

server side(here is weblogic) has its own identity and truststore(RESTful web service implemented by Jersey);

client side(here is a RESTful web service client) has its own identity and truststore, too;

Each side should have the other side’s identity in its truststore, to let the HTTPS two-way authentication works.

之前在glassfish上,server会自带identity和cacerts(相当于truststore)文件,要做的就是生成client的identity和truststore,并交换identity证书即可。

但是在weblogic中,默认自带的是demoIdentity和demoTrustStore,是不推荐在生产环境中使用的。推荐的方法是:使用custom identity和custom truststore,也就是需要自己生成server端的identity和truststore。步骤多了几个。

步骤多了倒不是问题,真正的问题出现在运行的时候。我运行的环境是本机的weblogic上部署的一个ear作为server,另一个war作为client。当client端每次访问server,控制台会抛出如下的错误:

1
2
<2011-7-12 下午05时35分12秒 CST> <Warning> <Security> <BEA-090477> <Certificate chain received from localhost - 127.0.0.1 was not trusted causing SSL handshake failure.> 
<2011-7-12 下午05时35分12秒 CST> <Warning> <Security> <BEA-090482> <BAD_CERTIFICATE alert was received from gang-office-laptop - 127.0.0.1. Check the peer to determine why it rejected the certificate chain (trusted CA configuration, hostname verification).

需要自己生成server端的identity和truststore。步骤多了几个。

步骤多了倒不是问题,真正的问题出现在运行的时候。我运行的环境是本机的weblogic上部署的一个ear作为server,另一个war作为client。当client端每次访问server,控制台会抛出如下的错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<2011-7-12 下午05时35分12秒 CST> <Warning> <Security> <BEA-090477> <Certificate chain received from localhost - 127.0.0.1 was not trusted causing SSL handshake failure.> 
<2011-7-12 下午05时35分12秒 CST> <Warning> <Security> <BEA-090482> <BAD_CERTIFICATE alert was received from gang-office-laptop - 127.0.0.1. Check the peer to determine why it rejected the certificate chain (trusted CA configuration, hostname verification). SSL debug tracing may be required to determine the exact reason the certificate was rejected.>
com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLKeyException: [Security:090477]Certificate chain received from localhost - 127.0.0.1 was not trusted causing SSL handshake failure.
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:131)
at com.sun.jersey.api.client.Client.handle(Client.java:616)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:559)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:72)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:454)
at com.oracle.tis.mcsp.RemoteIncidentTicketRepository.findUnSynchronized(RemoteIncidentTicketRepository.java:103)
at com.oracle.tis.mcsp.IncidentTicketProducer.produce(IncidentTicketProducer.java:43)
at com.oracle.tis.kaiser.McspIncidentTicketProducer.produce(McspIncidentTicketProducer.java:20)
at com.oracle.tis.AbstractSynchronizer.synchronize(AbstractSynchronizer.java:24)
at com.oracle.tis.job.SynchronizerQuartzJobBean.executeInternal(SynchronizerQuartzJobBean.java:30)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86)
at org.quartz.core.JobRunShell.run(JobRunShell.java:216)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)

这个问题困扰的我好几天,百思不得其解。

转机出现在:我试图从weblogic官方文档中找到线索,其中提到:可以通过配置JVM启动参数”-Dssl.debug=true -Dweblogic.StdoutDebugEnabled=true”来打印SSL相关的日志信息。我如法炮制。果然有更详细的相关信息出现:

1
2
3
4
5
6
7
8
9
10
11
<2011-7-13 上午11时24分28秒 CST> <Debug> <SecuritySSL> <BEA-000000> <434649 SSL3/TLS MAC> 
<2011-7-13 上午11时24分28秒 CST> <Debug> <SecuritySSL> <BEA-000000> <434649 received HANDSHAKE>
<2011-7-13 上午11时24分28秒 CST> <Debug> <SecuritySSL> <BEA-000000> <HANDSHAKEMESSAGE: Certificate>
<2011-7-13 上午11时24分28秒 CST> <Debug> <SecuritySSL> <BEA-000000> <Cannot complete the certificate chain: No trusted cert found>
<2011-7-13 上午11时24分28秒 CST> <Debug> <SecuritySSL> <BEA-000000> <Validating certificate 0 in the chain: Serial number: 1310034187
Issuer:C=US, ST=VA, L=Reston, O=SUN, OU=Engineering, CN=itsp
Subject:C=US, ST=VA, L=Reston, O=SUN, OU=Engineering, CN=itsp
Not Valid Before:Thu Jul 07 18:23:07 CST 2011
Not Valid After:Wed Oct 05 18:23:07 CST 2011
Signature Algorithm:SHA1withRSA
>

引起我注意的是证书信息里面的”CN=itsp”,这个名字是我给server的identity证书起的。按理说这个时候应该是server端检查client端的idenitity来进行认证,为什么会出现server端的idenitity证书信息呢?

我先是怀疑client端的identity keystore和truststore弄反了。为了验证这一点,我故意将现有client端的identity和truststore互相颠倒,再进行测试。测试的结果是:错误日志里面的证书信息依然是”CN=itsp”。

这就证明这里显示无法认证的证书,并不是从client端传过来的证书。如果不是client端的话,那就是server端自己的。为了验证我的想法,我把server端的identity导入了server的truststore(之前没有做过这一步),然后再跑。果然这个错误消失了!

我有点困惑的是:为什么server端认证的时候,要先验证自己的identity是否是被信任的(在truststore中)?也许这是SSL双向认证的一个步骤?

另外,这个问题之所以难以解决,是因为网上关于类似问题的解决方法基本没有,有一些还会把人引入歧途(比如这篇),所以着实让人郁闷。

以下是具体的配置步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
## Configure HTTPS certification of Kaiser TIS

## wls = Weblogic sever
# 1. Create the wls identity keystore (In portal server)
cd wldomains/itsp_domain/config # where the weblogic domain config file is.
$JAVA_HOME/bin/keytool -genkey -alias wls-identity -keyalg RSA -keypass changeit -storepass changeit -keystore wls_identity.jks -dname "CN=itsp, OU=Engineering, O=SUN, L=Reston, ST=VA, C=US"

# 2. Import the wls identity to the wls truststore (In portal server)
cd wldomains/itsp_domain/config # where the weblogic domain config file is.
$JAVA_HOME/bin/keytool -export -alias wls-identity -storepass changeit -file wls.cer -keystore wls_identity.jks
$JAVA_HOME/bin/keytool -import -v -trustcacerts -alias wls-identity -file wls.cer -keystore wls_truststore.jks -keypass changeit -storepass changeit

# 3. Create the Kaiser-adapter identity keystore (In TIS-adapter server)
cd certificate/v3/kaiser # where the keystore files of the adapter are placed.
$JAVA_HOME/bin/keytool -genkey -alias kaiser-identity -keyalg RSA -keypass changeit -storepass changeit -keystore kaiser_identity.jks -dname "CN=kp.org, OU=Engineering, O=SUN, L=Reston, ST=VA, C=US"

# 4. Import the Kaiser-adapter's identity into Weblogic trust keystore
# 4.1 Export the Kaiser-adapter identity to a cer file (In TIS-adapter server)
cd certificate/v3/kaiser # where the keystore files of the adapter are placed.
$JAVA_HOME/bin/keytool -export -alias kaiser-identity -storepass changeit -file kaiser.cer -keystore kaiser_identity.jks

# 4.2 Import the Kaiser-adapter identity from the cer file to the wls truststore (In portal server)
# First, please copy the kaiser.cer file got in the previous step into the following directory.

cd wldomains/itsp_domain/config # where the weblogic domain config file is.
$JAVA_HOME/bin/keytool -import -v -trustcacerts -alias kaiser-identity -file kaiser.cer -keystore wls_truststore.jks -keypass changeit -storepass changeit

# 5. Import wls's identity into Kaiser-adapter trust keystore
# 5.1 Export the wls's identity to a cer file (In portal server)
cd wldomains/itsp_domain/config # where the weblogic domain config file is.
$JAVA_HOME/bin/keytool -export -alias wls-identity -storepass changeit -file wls.cer -keystore wls_identity.jks

#5.2 Import the wls's identity from the cer file to the Kaiser-adapter truststore (In TIS-adatper server)
# First, please copy the wls.cer file got in the previous step into the following directory.
cd certificate/v3/kaiser # where the keystore files of the adapter are placed.
$JAVA_HOME/bin/keytool -import -v -trustcacerts -alias wls-identity -file wls.cer -keystore kaiser_truststore.jks -keypass changeit -storepass changeit

# After the steps above, in the portal server directory "wldomains/itsp_domain/config" there should be the following 2 files:
wls_identity.jks (has the following key: wls-identity)
wls_truststore.jks(has the following keys: wls-identity, kaiser-identity)

# In the Kaiser TIS adapter server directory "certificate/v3/kaiser" there should be the following 2 files:
kaiser_identity.jks(has the following key: kaiser-identity)
kaiser_truststore.jks(has the following key: wls-identity)

# 6. Configure Weblogic keystores
# Login weblogic console, go to "Environment -> Servers -> some_server -> tab 'Keystores' ", set:
# Keystores: Custom Identity and Custom Trust (select this item by clicking "change" button to see the candidate options);
# Custom Identity Keystore: /xxx/xxx/wls_identity.jks (Full path of where the "wls_identity.jks" file is);
# Custom Identity Keystore Type: jks
# Custom Identity Keystore Passphrase: changeit (the keystore password)

Comments