如何使用 JBoss 6 在 RMIIO 流上启用加密

How to enable encryption on a RMIIO stream using JBoss 6

我想加密 JBoss 6.1.0.Final 服务器和我的客户端之间的通信。为此,我通过 RMI 激活了 SSL,它运行良好。但是,我也使用 RMIIO,当我通过 RMI 激活 SSL 加密时,它没有自动加密。在最佳情况下,我想使用与加密 RMI 通信相同的加密技术。

这是我的配置:

server/myThing/deploy/远程处理-jboss-beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">

    <deployment xmlns="urn:jboss:bean-deployer:2.0">

       <bean name="UnifiedInvokerConnector" class="org.jboss.remoting.transport.Connector">
          <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.remoting:service=Connector,transport=socket",exposedInterface=org.jboss.remoting.transport.ConnectorMBean.class,registerDirectly=true)</annotation>
          <property name="serverConfiguration"><inject bean="UnifiedInvokerConfiguration"/></property>
          <!-- add this to configure the SSL socket for the UnifiedInvoker -->
          <property name="serverSocketFactory"><inject bean="SSLServerSocketFactoryEJB2"/></property>
       </bean>

       <!-- Remoting server configuration -->
       <bean name="UnifiedInvokerConfiguration" class="org.jboss.remoting.ServerConfiguration">
          <constructor>
             <!-- Changed from socket to sslsocket -->
             <parameter>sslsocket</parameter>
          </constructor>
          <!-- some other stuff, kept as the default config -->
       </bean>

       <!-- Some stuff removed to simplify the explanation -->

       <!-- Added for SSL security -->
       <bean name="SSLServerSocketFactoryEJB2" class="org.jboss.security.ssl.DomainServerSocketFactory">
         <constructor>
           <parameter><inject bean="EJB2SSLDomain"/></parameter>
         </constructor>
       </bean>

       <!-- Added for SSL security -->
       <bean name="EJB2SSLDomain" class="org.jboss.security.plugins.JaasSecurityDomain">
         <constructor>
           <parameter>EJB2SSLDomain</parameter>
         </constructor>
         <property name="keyStoreURL">C:\MyData\Security\ssl.keystore</property>
         <property name="keyStorePass">MyPassword</property>
         <property name="keyStoreAlias">MyAlias</property>
         <property name="trustStorePass">MyPassword</property>
       </bean>

    </deployment>

server/myThing/deploy/属性-service.xml

<server>

  <!-- some stuff removed -->

  <mbean code="org.jboss.varia.property.SystemPropertiesService" 
     name="jboss:type=Service,name=SystemProperties">

    <attribute name="Properties">
      com.healthmarketscience.rmiio.exporter.port=11099
    </attribute>

  </mbean>
</server>

我已经有一段时间没研究 RMI 和 SSL 了。但是,RMIIO 有一个特定的接口,允许您自定义底层 "remoting" 实现,RemoteStreamExporter. If you look at the DefaultRemoteStreamExporter implementation, you can see how the RMI objects are exported by default. My guess is that you want to use similar implementation which calls the 4 parameter export method 具有适当的 RMI SSL 套接字工厂。

这是我如何让它工作的,这是从 jtahlborn 的回答中推导出来的。

我在 RMI 上获得了 JBoss 配置,它是在 remoting-jboss-beans.xml 中配置的,并用它初始化了 SSLContext.setDefault。 JBoss 开始时调用代码。这是一个简化的例子。

KeyStore lKeyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
InputStream lISKeyStore = new FileInputStream( new File( "C:/Security/ssl.keystore" ) );
try
{
  lKeyStore.load( lISKeyStore, "MyPassword".toCharArray() );
}
finally
{
  lISKeyStore.close();
}
KeyManagerFactory lKeyManagerFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );
lKeyManagerFactory.init(lKeyStore, "MyPassword".toCharArray() );

KeyStore lTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream lIStrustStore = new FileInputStream( new File( "C:/Security/ssl.truststore" ) );
try
{
  lTrustStore.load(lIStrustStore, "MyPassword".toCharArray() );
}
finally
{
  lIStrustStore.close();
}

TrustManagerFactory lTrustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
lTrustManagerFactory.init(lTrustStore);

SSLContext lSSLContext = SSLContext.getInstance( "SSL" ); // Don't use SSLContext.getDefault() here it seems it's immutable.
lSSLContext.init( lKeyManagerFactory.getKeyManagers(), lTrustManagerFactory.getTrustManagers(), null );
SSLContext.setDefault( lSSLContext );

我还创建了自己的 RemoteStreamExporter

public class SSLRemoteStreamExporter extends DefaultRemoteStreamExporter
{
  @Override
  protected Object exportImpl(RemoteStreamServer<?,?> server)
      throws RemoteException
  {
    // The SslRMIServerSocketFactory uses SSLContext.getDefault() to retrieve the configuration. The default must be initialized with right values.
    return UnicastRemoteObject.exportObject(server, getPort(), new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory() );
  }
}

之后,我将 RMIIO 配置为使用我自己的 RemoteStreamExporter server/myThing/deploy/属性-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server>
<!-- $Id: properties-service.xml 16662 2003-08-27 04:38:22Z patriot1burke $ -->

    <server>

      <!-- some stuff removed -->

      <mbean code="org.jboss.varia.property.SystemPropertiesService" 
         name="jboss:type=Service,name=SystemProperties">

        <attribute name="Properties">
          com.healthmarketscience.rmiio.exporter.port=11099
          com.healthmarketscience.rmiio.exporter=SSLRemoteStreamExporter
        </attribute>

      </mbean>
    </server>