1 2 3 Previous Next 33 Replies Latest reply on Nov 2, 2016 2:17 PM by xibo_flair Go to original post
      • 15. Re: Re: Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
        ybxiang.china
                <security-realm name="ApplicationRealm">
                    <server-identities>
                        <ssl>
                            <keystore path="server.keystore" relative-to="jboss.server.config.dir" keystore-password="ybxiang_keystore_password"/>
                        </ssl>
                    </server-identities>
                    <authentication>
                        <jaas name="ybxiang-forum-jaas-security-domain"/>
                    </authentication>
                </security-realm>
        • 16. Re: Re: Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
          ybxiang.china

          I have read example, You linked. Unfortunately, there is no solution for me.

          First of all, there are some specific configuration entries in JBoss 7.2, that are not present in WildFly CR1 (and WildFly Final, I suppose). I mean some port configuration, jacorb configuration and "obsolete" security 1.2 subsystem in place of new 2.0 version.

          ~~~~~~~~~It is NOT difficult for a common developer to migrate configuration from 7.2 to 8.0.

           

          Secondly, it seems You are using SSL to secure HTTPS connection from web client,

          ~~~~~~~~~Please note: <security-realm name="ApplicationRealm">.<server-identities>.<ssl> in the standalone.xml.

           

          but I'm trying to achieve that with standalone client which use standard native interface.

          ~~~~~~~~~Why do you think so?  I had provided EJB client too.

           

          Thirdly, I can't find any reference to server.truststore in Your configuration.

          ~~~~~~~~~Please note: <security-realm name="ApplicationRealm">.<server-identities>.<ssl>.<keystore path="server.keystore" ...> in the standalone.xml.

           

          Are You sure that You're using public keys of both sides of communication to encrypt You transmission between standalone client and server?

          ~~~~~~~~~I am sure:

                           (a) server.keystore contains both public key and private key.

                           (b) client.truststore contains ONLY matched public key.

                           The client trust this public key.

          • 17. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
            ybxiang.china

            From what I remember when I upgraded from JBoss 7.2 to WildFly, to get SSL working for a remote EJB client, the following was necessary in standalone.xml:

            ~~~~~~~ There are maybe many kinds of configuration.

             

            WildFly will use the http-upgrade feature to switch the communication on the http port over to the remoting binary protocol.

            ~~~~~~ I am NOT sure if You and I undered the "multiplex" correctly.

             

                         In my examle, if you enable client's SSL, the transfer speed will get lower than that in non-ssl mode. I think this result can prove that SSL configuration works.

            • 18. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
              ybxiang.china

              I had migrated my product from jboss as 7.2.0 to wildfly-8.CR1 weeks ago.

              I think the SSL works well.

              I am using the http 80 port.

               

              Tomorrow morning, I will test the speeds in both SSL-mode and non-SSL mode, then post the configuration and results here.

              If I have enough time, I will do some other test. For example ports filtering in firewall.

              • 19. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                damian.petrecki

                You didn't understand me..

                I need to configure server keystore with server private key and client truststore with server public key. Then I need client private key in client keystore and client public key in server truststore.

                Then I will be able to encrypt client-to-server messages using server pubic key (and server will be the only one who can read these messages) and encrypt server-to-client messages with client public key. I will be able to verify each sides of communication and encrypt every message, using long, SHA-256 key inside TLSv1.2 protocol.

                So, I need to configure server truststore and client keystore as well as client truststore and server keystore.

                 

                I have written all engine of this communication OUTSIDE ANY SERVER (with JSSE, TLS, both sides verification and transmission encryption), but I wanted to do it in "enterprise" way. As far, I can tell You, that every modern, "enterprise", "business" solutions are very hard to use, when You are trying to do something, that is not described at first page of google query result.

                I'm java developer for some time and I still can't see many advantages of JEE over JSE. Every time, when I'm trying to use JBoss, GlassFish or any other "big Java EE server" to my own purposes (I use JBoss in my workplace), I meet the strange obstacles and I have to spend a lot time to build something that is really easy to me in standard Java environment (without EJB, Context management, strange entity management and some on).

                 

                Dear Xiang Yingbing. I really appreciate Your help, but please - try to examinate Your standalone EJB client and WildFly Server with configuration, You posted. Use Wireshark and take a look at every unencrypted messages in Your application. When I will have some spare time, I will record a video of this behavior for You.

                 

                Sorry for my english, I really don't use it every day:)

                • 20. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                  ybxiang.china

                  Dear Petrecki,

                           I am sorry I misunderstood you.

                   

                           What I said is SSL(unidirection), NOT TLS(bi-direction).

                           My configuration for EJB over SSL is from here: Remoting-connector with SSL

                   

                  I have checked my EJB client (although it is SSL, NOT TLS) with Wildfly-8.0.0-CR1.

                  (1) TimeConsuming Test is finished.

                      (a) If I use p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "true");

                          then,

                                  Round-1: We spend 3838/3994/3418 ms to retrieve 50000bytes 3 times

                                  Round-2: We spend 7161/6022/5790 ms to retrieve 100000bytes 3 times

                      (b) If I use p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");

                          then,

                                  Round-1: We spend 2980/2513/2934 ms to retrieve 50000bytes 3 times

                                  Round-2: We spend 6084/5368/5227 ms to retrieve 100000bytes 3 times

                  (2) Wireshark test is undergoing.

                        I had tried to use Wireshark to analyze those data one year ago, but all data were messy code, so I did NOT do more research.

                        I will find sometime to test it again.

                   

                   

                   

                  AS to TLS configuration, I will do some research soon.

                  I think you can read jboss-7 or wildfly-8 document at the same time:

                  https://docs.jboss.org/author/display/JBASDOC/Home? (especially Detailed Configuration - JBoss AS 7.2 - Project Documentation Editor)

                        NOTE: wildfly-8's doc is NOT finished yet. That is why I did NOT suggest you to use wildfly8 so early.

                  • 21. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                    ybxiang.china

                    I forget one thing,

                          If we want to configure TLS, maybe we should configure more XNIO options (jboss as 7 and wildfly8 use XNIO) on client side:

                                p.put("remote.connection.default.connect.options.org.xnio.Options.XXXXXX", "true");

                         Those options can be found in org.xnio.Options.

                     

                    I had tried to research XNIO, but it is NOT easy.

                    • 22. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                      damian.petrecki

                      As far as I can see, there is two ways to configure SSL/TLS on server side and I don't know, which one is correct.

                      I can configure JSSE in Security Domain authenticaion (with keystore, truststore and client verification obligatory) and add this domain to realm.

                      On the other hand I can configure SSL keystore in Security Realm server identities and truststore in Security Realm authentication.

                       

                      There are also two ways to configure client. I can add xnio options to properties used to create PropertiesBasedEJBClientConfiguration but I can also add these settings to jndi properties.

                      Moreover, I probably can't set client keystore and truststore by "System.setProperty(...)" but I have to use my own TrustManager.

                      I'm not even sure, if I can use "remote.connection.default.username" and "remote.connection.default.password" to set credentials, or I should write CallbackHandler.

                      • 23. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                        damian.petrecki

                        Darren, Could You, please, send me Your entire standalone.xml? I still can't get it working...

                        • 24. Re: Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                          darrenjones

                          I came up with a trivial example, which is attached. To get going, start with a fresh copy of WildFly 8 CR1. Create an Application user (with the add-user script) called gandalf, password gandalf. Then, take the "ping-ejb-1.0-SNAPSHOT.jar" (already built in the attached, target folder) and put it in your standalone/deployments folder.

                           

                          At this point, if you run WildFly with the out-of-the-box standalone.xml, you will be able to use the ping-client code with the "lookupHttp" method to call the ping EJB successfully.

                           

                          If you then copy the standalone-ping.xml to standalone/configuration, (set your own keystore details in the ssl server-identity, copy the keystore into deployments), and restart wildfly with "standalone -c standalone-ping.xml", it will be using https for EJB calls. If you modify ping-client to call lookupHttps instead, it should succeed.

                           

                          Currently, the ping-client trust manager accepts any certificates from the server, but that could easily be changed.

                          • 25. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                            damian.petrecki

                            Thanks for Your answer. Unfortunately it isn't solution I'm looking for.

                            1. In Your code, server key is used to encrypt session key to use in further communication.

                            2. Client doesn't have own key so cannot be verified on server.

                            3. Communication is encrypted with session scoped, symmetric key (3DES I guess)

                            In Your solution transmission can be encrypted but this isn't strong security algorithm.

                             

                            I want to use asymmetric encryption. I want client to use server public key to encrypt messages so only true server can decrypt them with server private key. Of course server answers should be encrypted with client public key to be "decryptable" only by client. Now I'm not sure if it is even possible.

                            • 26. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                              darrenjones

                              No problem - sorry it wasn't what you were after.

                               

                              I noticed that the <https-connector> in the undertow subsystem supports an attribute of verify-client="REQUIRED", which may enable two-way certificate verification in the SSL handshake, but I don't understand it well enough yet to try it out.

                               

                              And it sounds like that does not go far enough - even if the SSL negotation was two way, you want to send encrypted data within the already-encrypted SSL transmission stream.

                               

                              I don't think I can help any further, but good luck.

                              • 27. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                                damian.petrecki

                                Thank You for Your help. I will post solution, when I find it out.

                                • 28. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                                  damian.petrecki

                                  I've found the solution.

                                  There are several steps to re-create my system:

                                   

                                  First of all, You have to create pair of server keys (private and public) and pair of client keys:

                                  keytool -genkeypair -alias serverkey -keyalg RSA -keysize 2048 -validity 7360 -keystore server.keystore
                                  keytool -genkeypair -alias clientkey -keyalg RSA -keysize 2048 -validity 7360 -keystore client.keystore
                                  
                                  
                                  

                                   

                                  Then, export certificates from keys:

                                  keytool -export -alias serverkey -keystore server.keystore -rfc -file server.crt
                                  keytool -export -alias clientkey -keystore client.keystore -rfc -file client.crt
                                  
                                  
                                  

                                   

                                  Export public keys from certificates and import them into truststores:

                                  keytool -import -file server.crt -keystore client.truststore
                                  keytool -import -file client.crt -keystore server.truststore
                                  
                                  
                                  

                                   

                                  A've created 3 projects: api, server and client.

                                  In "api" project, I have classes MyLogicRemote, MyLogicLocal and MyLogicCommon

                                  @Remote
                                  public interface MyLogicRemote extends MyLogicCommon{
                                  }
                                  @Local
                                  public interface MyLogicLocal extends MyLogicCommon{
                                  }
                                  public interface MyLogicCommon extends Serializable{
                                      public abstract String seyHello();
                                  }
                                  
                                  
                                  

                                  Project "server" contains MyLogicBean:

                                  @Stateless (name = "MyLogic")

                                  public class SystemInfoBean implements MyLogicRemote, MyLogicLocal {
                                      @Override
                                      @RolesAllowed("My own role 1")
                                      public String seyHello() {
                                          return "Hello, World!";
                                      }
                                  }
                                  
                                  
                                  

                                  "client" project is a tricky part. You have to had Client class and client keystore and truststore here.

                                  Client config properties are first of two the most important parts to achieve SSL/TLS encryption/signing.

                                  public class Client {
                                  
                                      public static void main(String[] args) throws NamingException { //You should handle this exception!!!
                                          System.setProperty("javax.net.ssl.keyStore", "client.keystore"); //change it
                                          System.setProperty("javax.net.ssl.trustStore", "client.truststore"); //change it
                                          System.setProperty("javax.net.ssl.keyStorePassword", "password@123"); //change it
                                          System.setProperty("javax.net.ssl.trustStorePassword", "password@123"); //change it
                                        
                                          final Properties clientConfigProps = new Properties();
                                          clientConfigProps.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "true");
                                          clientConfigProps.put("remote.connections", "default");
                                          clientConfigProps.put("remote.connection.default.host", "192.168.0.1"); //change it
                                          clientConfigProps.put("remote.connection.default.port", "8443");
                                          clientConfigProps.put("remote.connection.default.protocol", "https-remoting");
                                          clientConfigProps.put("remote.connection.default.username", "admin"); //change it
                                          clientConfigProps.put("remote.connection.default.password", "password"); //change it
                                          clientConfigProps.put("remote.connection.default.connect.timeout", "60000");
                                          clientConfigProps.put("remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
                                  
                                          final EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(clientConfigProps);
                                          final ContextSelector<EJBClientContext> ejbClientContextSelector = new ConfigBasedEJBClientContextSelector(ejbClientConfiguration);
                                  
                                          EJBClientContext.setSelector(ejbClientContextSelector);
                                  
                                          final Properties jndiProperties = new Properties();
                                          jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
                                          Context ctx = new InitialContext(jndiProperties);
                                          MyLogicRemote bean = (MyLogicRemote) ctx.lookup("ejb:MyAppName/server-0.0.1-SNAPSHOT/MyLogic!cannonical.path.to.MyLogicRemote") //ejb:application name/module name/bean name!cannonical path to bean remote interface
                                          System.out.println(bean.seyHello);
                                      }
                                  }
                                  
                                  
                                  

                                  I've added "api" project to dependency of client and server using Maven, created JAR from "client" and EJB (in JAR in EAR) from "server". You can do that manually, with ant, or whatever You like.

                                   

                                  We need MySQL database with three tables:

                                  user(login, password), role(id, role, description), user_role(user_login, role_id)
                                  
                                  
                                  

                                  Be sure to fill password in database with

                                  org.jboss.security.Util.createPasswordHash("SHA-256", "base64", "utf-8", "admin", "password")
                                  
                                  
                                  

                                  , add role "My own role 1" and connect them in user_role table.

                                  My database is on the same host as WildFly server.

                                  Today WildFly 8.0 Final has been released and I've tested my solution on this version.

                                  So... You need to download fresh copy of server and take three actions: copy server truststore and keystore to standalone/configuration directory, deploy our application and MySQL Connector and configure standalone.xml. Proper server configuration is second of two the most important parts of our puzzles.

                                  My standalone looks like (only relevant parts):

                                  ...
                                  <security-realm name="ApplicationRealm">     
                                      <authentication>
                                          <jaas name="other"/>
                                      </authentication>
                                  </security-realm>
                                  <security-realm name="SSLRealm">     
                                      <server-identities>
                                          <ssl>
                                              <keystore path="server.keystore" relative-to="jboss.server.config.dir" keystore-password="password@123" alias="stampserverkey"/>
                                          </ssl>
                                      </server-identities>
                                      <authentication>
                                          <truststore path="server.truststore" relative-to="jboss.server.config.dir" keystore-password="password@123"/>
                                      </authentication>
                                  </security-realm>
                                  ... 
                                  <datasources>
                                  ...
                                  <datasource jta="false" jndi-name="java:jboss/datasources/MyDS" pool-name="myDS" enabled="true" use-ccm="false">
                                       <connection-url>jdbc:mysql://localhost:3306/schemaName</connection-url>
                                       <driver-class>com.mysql.jdbc.Driver</driver-class>
                                       <driver>mysql-connector-java-5.1.28-bin.jar</driver>
                                       <security>
                                           <user-name>databaseuser</user-name>
                                           <password>databasepassword</password>
                                       </security>
                                       <validation>
                                          <validate-on-match>false</validate-on-match>
                                          <background-validation>false</background-validation>
                                       </validation>
                                       <statement>
                                           <share-prepared-statements>false</share-prepared-statements>
                                       </statement>
                                  </datasource>     
                                  ...
                                  <subsystem xmlns="urn:jboss:domain:ejb3:2.0">
                                  ...
                                  <remote connector-ref="https-remoting-connector" thread-pool-name="default"/>
                                  <!-- instead <remote connector-ref="http-remoting-connector" thread-pool-name="default"/> -->
                                  ...
                                  </subsystem>
                                  <subsystem xmlns="urn:jboss:domain:security:1.2">
                                      <security-domains>
                                          <security-domain name="other" cache-type="default">
                                              <authentication>
                                                  <login-module code="Database" flag="required">
                                                      <module-option name="dsJndiName" value="java:jboss/datasources/MyDS"/>
                                                      <module-option name="principalsQuery" value="SELECT password FROM user WHERE login=?"/>
                                                      <module-option name="rolesQuery" value="SELECT r.role, 'Roles' from role r JOIN user_role u ON u.id = r.role_id where u.login =?"/>
                                                      <module-option name="password-stacking" value="useFirstPass"/>
                                                      <module-option name="hashAlgorithm" value="SHA-256"/>
                                                      <module-option name="hashEncoding" value="base64"/>
                                                      <module-option name="hashCharset" value="utf-8"/>
                                                  </login-module>
                                              </authentication>
                                          </security-domain>
                                          ...
                                  </subsystem>
                                  <subsystem xmlns="urn:jboss:domain:remoting:2.0">
                                      <endpoint worker="default"/>
                                      <http-connector name="https-remoting-connector" connector-ref="default-https" security-realm="ApplicationRealm"/>          
                                  </subsystem>
                                  ...
                                  <subsystem xmlns="urn:jboss:domain:undertow:1.0">
                                  ...
                                      <server name="default-server">
                                          <https-listener name="default-https" socket-binding="https" security-realm="SSLRealm" verify-client="REQUIRED"/>
                                          ...
                                      </server>
                                  ...  
                                  </subsystem>  
                                  ...
                                  <!-- very unsecure, for testing purposes only -->
                                      <interfaces>
                                          <interface name="management">
                                              <nic name="eth0"/>
                                          </interface>
                                          <interface name="public">
                                              <nic name="eth0"/>
                                          </interface>
                                          <interface name="unsecure">
                                              <nic name="eth0"/>
                                          </interface>
                                      </interfaces>
                                  
                                  
                                  

                                   

                                  And... That all!

                                  Have a nice programming

                                  • 29. Re: How to use SSL/TLS encryption and database authorization/authentication to call EJB in WildFly 8 CR1?
                                    andreas.kozma

                                    Amazing job, Damian!!

                                     

                                    This was a tough nut to crack! We've been trying to solve the same problem for the last 1.5 months without success! The documentation should be much approved, as it is not clear at all how the security-realms interact with the security-domains, etc. The many confused posts and questions are ample proof for this lack of documentation.

                                     

                                    Thanks again for this post!

                                    - Andreas