我无法通过Java客户端使用PKCS12 ssl证书从Weblogic服务器获取mbeans。
用于创建自签名证书的服务器端命令: 使用Weblogic CertGen实用程序,Weblogic CertGenCA.der和证书颁发机构创建证书。
java utils.CertGen -certfile ServerCert -keyfile ServerKey -keyfilepass keypass
java utils.der2pem CertGenCA.der
type serverCert.pem CertGenCA.pem >> myCert.pem
Server Keystore created>>
java utils.ImportPrivateKey -keystore SeverIdentity.jks -storepass storepass -storetype JKS \
-keypass keypass -alias mykey -certfile myCert.pem -keyfile ServerKey.pem \
-keyfilepass keypass
Server Truststore used>>
DemoTrust.jks (Default Weblogic truststore)
用于创建PKCS12自签名证书的客户端命令:
java utils.CertGen -certfile ClientCert -keyfile ClientKey -keyfilepass keypass
openssl pkcs12 -export -in ClientCert.pem -inkey ClientKey.pem -out client-pkcs-12-cert
在Weblogic管理控制台中完成配置:
Keystores: Custom Identity Custom Trust.
Custom Identity Keystore: D:\certificate\latest\pkcs\SeverIdentity.jks
Custom Identity Keystore Type: JKS
Custom Identity Keystore Passphrase: storepass (same as –storepass value of ImportPrivateKey)
Confirm Custom Identity Keystore Passphrase: storepass
Custom Trust Keystore: D:\certificate\latest\pkcs\DemoTrust.jks
Custom Trust Keystore Type: JKS
Custom Trust Keystore Passphrase: DemoTrustKeyStorePassPhrase
Custom Trust Keystore Passphrase: DemoTrustKeyStorePassPhrase
在setDomainEnv.cmd中完成的配置:
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9191 \
-Dcom.sun.management.jmxremote.ssl=true -Dcom.sun.management.jmxremote.authenticate=false \
-Djavax.net.ssl.keyStore=D:\certificate\latest\pkcs\SeverIdentity.jks \
-Djavax.net.ssl.keyStorePassword=keypass -Djavax.net.ssl.trustStore=D:\certificate\latest\pkcs\DemoTrust.jks \
-Djavax.net.ssl.trustStorePassword=DemoTrustKeyStorePassPhrase -Djava.rmi.server.hostname=10.112.69.200
参考:http://www.weblogic-tips.com/2010/05/20/two-way-ssl-on-weblogic-server/
Java客户端代码:
public static void main22(String args[]) {
try {
System.setProperty("javax.net.ssl.keyStore",
"D://certificate//latest//client-pkcs-12-cert");
System.setProperty("javax.net.ssl.keyStorePassword", "keypass");
HashMap<String, Object> env = new HashMap<String, Object>();
String truststore = "D://certificate//latest//client-pkcs-12-cert";
char truststorepass[] = "keypass".toCharArray();
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(new FileInputStream(truststore), truststorepass);
TrustManagerFactory tmf = TrustManagerFactory
.getInstance("SunX509");
tmf.init(ks);
SSLContext ctx = SSLContext.getInstance("TLSv1");
ctx.init(null, tmf.getTrustManagers(), null);
SSLSocketFactory ssf = ctx.getSocketFactory();
env.put("jmx.remote.tls.socket.factory", ssf);
JMXServiceURL address = new JMXServiceURL("rmi", "", 0,
"/jndi/rmi://localhost:9191/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(address, env);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
Set<ObjectInstance> beans = mbsc.queryMBeans(null, null);
for (ObjectInstance instance : beans) {
MBeanInfo info = mbsc.getMBeanInfo(instance.getObjectName());
System.out.println(info);
}
jmxc.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("error :" + e.getMessage());
}
}
我可以在使用JKS证书时获取mbeans但是当我使用PKCS12证书时,它在通过JMXConnectorFactory连接时出现以下错误: 行异常:JMXConnector jmxc = JMXConnectorFactory.connect(address,env);
例外:
java.rmi.ConnectIOException: Exception creating connection to: 10.112.69.200; nested exception is:
java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:614)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:110)
at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)
at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2327)
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:277)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:248)
at test.Test.main(Test.java:68)
Caused by: java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
at javax.net.ssl.DefaultSSLSocketFactory.throwException(SSLSocketFactory.java:179)
at javax.net.ssl.DefaultSSLSocketFactory.createSocket(SSLSocketFactory.java:192)
at javax.rmi.ssl.SslRMIClientSocketFactory.createSocket(SslRMIClientSocketFactory.java:105)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
... 8 more
Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
at java.security.Provider$Service.newInstance(Provider.java:1245)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:220)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:147)
at javax.net.ssl.SSLContext.getInstance(SSLContext.java:125)
at javax.net.ssl.SSLContext.getDefault(SSLContext.java:68)
at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:102)
at javax.rmi.ssl.SslRMIClientSocketFactory.getDefaultClientSocketFactory(SslRMIClientSocketFactory.java:192)
at javax.rmi.ssl.SslRMIClientSocketFactory.createSocket(SslRMIClientSocketFactory.java:102)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
at sun.rmi.transport.DGCImpl_Stub.dirty(Unknown Source)
at sun.rmi.transport.DGCClient$EndpointEntry.makeDirtyCall(DGCClient.java:342)
at sun.rmi.transport.DGCClient$EndpointEntry.registerRefs(DGCClient.java:285)
at sun.rmi.transport.DGCClient.registerRefs(DGCClient.java:121)
at sun.rmi.transport.ConnectionInputStream.registerRefs(ConnectionInputStream.java:80)
at sun.rmi.transport.StreamRemoteCall.releaseInputStream(StreamRemoteCall.java:138)
at sun.rmi.transport.StreamRemoteCall.done(StreamRemoteCall.java:292)
at sun.rmi.server.UnicastRef.done(UnicastRef.java:431)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:97)
at com.sun.jndi.toolkit.url.GenericURLContext.lookup(GenericURLContext.java:185)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at javax.management.remote.rmi.RMIConnector.findRMIServerJNDI(RMIConnector.java:1886)
at javax.management.remote.rmi.RMIConnector.findRMIServer(RMIConnector.java:1856)
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:255)
... 2 more
Caused by: java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.
at sun.security.util.DerInputStream.getLength(DerInputStream.java:544)
at sun.security.util.DerValue.init(DerValue.java:347)
at sun.security.util.DerValue.<init>(DerValue.java:303)
at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1200)
at java.security.KeyStore.load(KeyStore.java:1185)
at com.sun.net.ssl.internal.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(TrustManagerFactoryImpl.java:202)
at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.getDefaultTrustManager(DefaultSSLContextImpl.java:70)
at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.<init>(DefaultSSLContextImpl.java:40)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:357)
at java.lang.Class.newInstance(Class.java:310)
at java.security.Provider$Service.newInstance(Provider.java:1221)
... 28 more
error :Exception creating connection to: 10.112.69.200; nested exception is:
java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
答案 0 :(得分:2)
首先,......(编辑:我意识到我误读了部分错误,我的第一点肯定至少部分不正确。)
快速搜索您的错误消息(java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.
)指向this IBM support page,建议使用JKS密钥库而不是PKCS#12(在服务器端,您没有这样做)或者证书中有不正确的字符。
其次,即使修复了服务器证书问题,也无法使用此代码进行客户端证书身份验证。
String truststore = "D://certificate//latest//client-pkcs-12-cert";
char truststorepass[] = "keypass".toCharArray();
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(new FileInputStream(truststore), truststorepass);
TrustManagerFactory tmf = TrustManagerFactory
.getInstance("SunX509");
tmf.init(ks);
SSLContext ctx = SSLContext.getInstance("TLSv1");
ctx.init(null, tmf.getTrustManagers(), null);
PKCS#12文件应包含您的客户端证书及其私钥。它旨在用作密钥库,而不是信任库。也就是说,虽然在这两种情况下都将实体称为密钥库,但您可以将其与密钥管理器一起使用,而不是信任管理器。
在这里,您正在使用PKCS#12文件初始化SSLContext
的信任管理器。这是你应该初始化的关键经理。
此外,如果您的代码使用的是与Sun / Oracle / OpenJDK无关的JRE,则应该避免硬编码“SunX509”,而是使用TrustManagerFactory.getDefaultAlgorthim()
代替(实施此阶段时KeyManagerFactory
。)