12782

How to set the hibernate.connection.password as an encrypted value in hibernate.cfg.xml and then dec

Question:

I am trying to create a encrypted value in the properties for hibernate.connection.password. At run time the encrypted value is picked up and decrypted. I then try to overwrite the properties in the HibernateUtil. But even after decryption the value doesn't seemed to be used because it fails to authenticate. How would I get this to work?

public class HibernateUtil { private static final SessionFactory sessionFactory; private static ServiceRegistry serviceRegistry; private static final String keyFile="/keys/.aoo1key"; static { try { Configuration cfg = new Configuration().configure("hibernate.cfg.xml"); String passwordToDecrypt=cfg.getProperty("hibernate.connection.password"); if(passwordToDecrypt.startsWith("ENC(")&&passwordToDecrypt.endsWith(")")) { passwordToDecrypt = passwordToDecrypt.substring(4,passwordToDecrypt.length()-1); PropertiesEncryption propertiesEncryption = new PropertiesEncryption(keyFile); String decrypted = propertiesEncryption.decryptValue(passwordToDecrypt); cfg.setProperty("hibernate.connection.password", decrypted); } StandardServiceRegistry standardRegistry = cfg.getStandardServiceRegistryBuilder().build(); Metadata metaData = new MetadataSources(standardRegistry).getMetadataBuilder().build(); sessionFactory = metaData.getSessionFactoryBuilder().build(); } catch (Throwable th) { System.err.println("Enitial SessionFactory creation failed" + th); throw new ExceptionInInitializerError(th); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://www.hibernate.org/dtd/hibernate-configuration"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate5</property> <property name="hibernate.connection.username">root</property> <!-- <property name="hibernate.connection.password">dog</property> --> <property name="hibernate.connection.password">ENC(MYFBqlDom8ZawVi+toB3PU0MdI10Desvsq4D2Z5lejk=)</property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.current_session_context_class">thread</property> <mapping class="net.model.Employee" /> </session-factory> </hibernate-configuration>

The Exception

Enitial SessionFactory creation failedorg.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] Exception in thread "main" java.lang.ExceptionInInitializerError at net.roseindia.HibernateUtil.<clinit>(HibernateUtil.java:66) at net.roseindia.GetAllData.main(GetAllData.java:18) Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:271) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:233) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210) at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51) at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:242) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83) at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418) at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87) at net.roseindia.HibernateUtil.<clinit>(HibernateUtil.java:60) ... 1 more Caused by: org.hibernate.exception.JDBCConnectionException: Error calling Driver#connect at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator$1$1.convert(BasicConnectionCreator.java:105) at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:123) at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:41) at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:58) at org.hibernate.engine.jdbc.connections.internal.PooledConnections.addConnections(PooledConnections.java:123) at org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init>(PooledConnections.java:42) at org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init>(PooledConnections.java:20) at org.hibernate.engine.jdbc.connections.internal.PooledConnections$Builder.build(PooledConnections.java:161) at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildPool(DriverManagerConnectionProviderImpl.java:109) at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:72) at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94) at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:242) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66) at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88) at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:259) ... 13 more Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:910) at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3923) at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1273) at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2031) at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:718) at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302) at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282) at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:38) ... 28 more

Answer1:

I found that if I broke it down into steps I can get it to do what I want. I was doing the build at the same time I was instantiating the StandardServiceRegistry. That seems to have been the main problem with my code. Plus I found that I should set the decrypted password with standardServiceRegistryBuilder.applySetting and not with the Configuration object.

StandardServiceRegistry standardRegistry = cfg.getStandardServiceRegistryBuilder().build();

it works like this

public class HibernateUtil { private static StandardServiceRegistry serviceRegistry; private static SessionFactory sessionFactory =buildSessionFactory(); private static final String keyFile="/keys/.aoo1key"; // Hibernate 5: private static SessionFactory buildSessionFactory() { try { Configuration cfg = new Configuration().configure("hibernate.cfg.xml"); // Create the ServiceRegistry from hibernate.cfg.xml StandardServiceRegistryBuilder standardServiceRegistryBuilder = cfg.getStandardServiceRegistryBuilder(); //Get the encrypted value String passwordToDecrypt=cfg.getProperty("hibernate.connection.password"); //Test if it is encrypted if(passwordToDecrypt.startsWith("ENC(")&&passwordToDecrypt.endsWith(")")) { //Stripping "ENC(" and ")" passwordToDecrypt = passwordToDecrypt.substring(4,passwordToDecrypt.length()-1); //TODO Key file is the key to use for decrytion, the name of my class PropertiesEncryption is kind of bad, what should I call it? PropertiesEncryption propertiesEncryption = new PropertiesEncryption(keyFile); String decrypted = propertiesEncryption.decryptValue(passwordToDecrypt); //Overwrite the encrypted value standardServiceRegistryBuilder.applySetting("hibernate.connection.password", decrypted); } //This will build even if the password wasn't never encrypted serviceRegistry =standardServiceRegistryBuilder.build(); // Create a metadata sources using the specified service registry. Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build(); return metadata.getSessionFactoryBuilder().build(); } catch (Throwable ex) { if (serviceRegistry != null) { StandardServiceRegistryBuilder.destroy(serviceRegistry); } throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { // Close caches and connection pools // getSessionFactory().close(); if (serviceRegistry != null) { StandardServiceRegistryBuilder.destroy(serviceRegistry); } } }

Recommend

  • Login form issue with spring security 2.0.7 and spring 2.5
  • Dynamic Event Handler not Firing
  • a:first-child modifying all links within my list
  • Overriding window.location on Webbrowser Control
  • Declaration of does not work with Ionic's ion-nav-view in IBM MobileFirst
  • Spring bean validation messages resolution
  • Migrating from java 1.4 ,EJB 1 to Java 6 and EJB 3 [closed]
  • Hibernate - Cannot connect to DB
  • NHibernate proxyexception
  • How to add regEx in angular filter
  • Sybase Error Implicit Conversion from datatype 'VARCHAR' to 'INT' not allowed
  • Updating Dojo provide
  • How can I include If-None-Match header in HttpRequestMessage
  • Bootstrap (v3.3.4) glyphicons not displayed in IE when refresh page (F5)
  • Is there some graphical way to create my own configuration file on SonarLint?
  • Spring Cloud Microservice Architecture Confusion
  • Parse a date string in a specific locale (not timezone!)
  • Should I or shouldn't I use the CachingConnectionFactory with hornetq 2.4.1
  • How can I extract results of aggregate queries in slick?
  • SplFileObject error failed to open stream: No such file or directory
  • Database structure design with variable amounts of fields
  • Debugging ASP.NET on a built-in web server suddenly stops
  • How can I send an e-mail from a vbs script
  • Display issues when we change from one jquery mobile page to another in firefox
  • How do I fake an specific browser client when using Java's Net library?
  • How to get a value (ex: baseURL) in every Karate feature?
  • How can I use Kendo UI with Razor?
  • Do I've to free mysql result after storing it?
  • Is there a mandatory requirement to switch app.yaml?
  • InvalidAuthenticityToken between subdomains when logging in with Rails app
  • JTable with a ScrollPane misbehaving
  • unknown Exception android
  • Checking variable from a different class in C#
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • Observable and ngFor in Angular 2
  • How to Embed XSL into XML
  • failed to connect to specific WiFi in android programmatically
  • UserPrincipal.Current returns apppool on IIS
  • Conditional In-Line CSS for IE and Others?
  • How can I use threading to 'tick' a timer to be accessed by other threads?