SSM implements the mysql database account password ciphertext login function

SSM implements the mysql database account password ciphertext login function

introduction

Our company is engaged in the research and development of some projects involving information security and confidential applications, which is divided into three steps. Compared with general companies and general projects, the requirements for information security are more stringent. The leaders require that the data volume and the user's username and password information must be configured and stored in ciphertext. This involves the database username and password in the jdbc.properties file. The same is true. The ciphertext needs to be configured and then loaded and decrypted as plaintext to connect to the database. The following is the implementation process, which is divided into three steps.

1. Create the DESUtil class

Provide custom keys, encryption and decryption methods.

package com.hzdy.DCAD.common.util;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;
/**
 * Created by Wongy on 2019/8/8.
 */
public class DESUtil {
  private static Key key;
  //Own keyprivate static String KEY_STR = "mykey";
  static {
    try {
      KeyGenerator generator = KeyGenerator.getInstance("DES");
      SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
      secureRandom.setSeed(KEY_STR.getBytes());
      generator.init(secureRandom);
      key = generator.generateKey();
      generator = null;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * Encrypt the string and return the BASE64 encrypted string*
   * @param str
   * @return
   * @see [class, class#method, class#member]
   */
  public static String getEncryptString(String str) {
    BASE64Encoder base64Encoder = new BASE64Encoder();
    try {
      byte[] strBytes = str.getBytes("UTF-8");
      Cipher cipher = Cipher.getInstance("DES");
      cipher.init(Cipher.ENCRYPT_MODE, key);
      byte[] encryptStrBytes = cipher.doFinal(strBytes);
      return base64Encoder.encode(encryptStrBytes);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * Decrypt the BASE64 encrypted string *
   */
  public static String getDecryptString(String str) {
    BASE64Decoder base64Decoder = new BASE64Decoder();
    try {
      byte[] strBytes = base64Decoder.decodeBuffer(str);
      Cipher cipher = Cipher.getInstance("DES");
      cipher.init(Cipher.DECRYPT_MODE, key);
      byte[] encryptStrBytes = cipher.doFinal(strBytes);
      return new String(encryptStrBytes, "UTF-8");
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  public static void main(String[] args) {
    String name = "dbuser";
    String password = "waction2016";
    String encryname = getEncryptString(name);
    String encrypassword = getEncryptString(password);
    System.out.println("encryname : " + encryname);
    System.out.println("encrypassword : " + encrypassword);
    System.out.println("name : " + getDecryptString(encryname));
    System.out.println("password : " + getDecryptString(encrypassword));
  }
}

2. Create the EncryptPropertyPlaceholderConfigurer class

Create an association with a profile.

package com.hzdy.DCAD.common.util;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
  //The property must remain consistent with the KEY of the configuration file private String[] encryptPropNames = {"jdbc.username", "jdbc.password"};
  @Override
  protected String convertProperty(String propertyName, String propertyValue) {
    //If the property is found in the list of encrypted properties if (isEncryptProp(propertyName)) {
      String decryptValue = DESUtil.getDecryptString(propertyValue);
      System.out.println(decryptValue);
      return decryptValue;
    } else {
      return propertyValue;
    }
  }
  private boolean isEncryptProp(String propertyName) {
    for (String encryptName : encryptPropNames) {
      if (encryptName.equals(propertyName)) {
        return true;
      }
    }
    return false;
  }
}

3. Modify the configuration file jdbc.properties

#Before encrypting the configuration#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.user=root
#jdbc.password=root
#jdbc.url=jdbc:mysql://localhost:3306/bookstore
#After encryption configuration jdbc.driver=com.mysql.jdbc.Driver
jdbc.user=Ov4j7fKiCzY=
jdbc.password=Ov4j7fKiCzY=
jdbc.url=jdbc:mysql://localhost:3306/bookstore

4. Modify the spring-content.xml configuration file

Change <context:property-placeholder location="classpath:.properties" /> in spring-context
 Modify to <bean class="com.hzdy.DCAD.common.util.EncryptPropertyPlaceholderConfigurer"p:locations="classpath:*.properties"/>
 //Note that there can only be one bean that reads the configuration file, otherwise the system will only read the first one

Note: If you find that username and password configured with ciphertext can be loaded and decrypted successfully, but the final connection is still connected in ciphertext and an error is reported, this may involve the problem of memory preloading. Once the project is started, the program will encrypt the ciphertext username and password. Even if the decryption is successful in the end, the final connection to the database is still read in ciphertext. At this time, we can rewrite the connection pool method ourselves, let spring-content.xml load the rewritten connection pool method, and decrypt it in advance when connecting.

package com.thinkgem.jeesite.common.encrypt;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.security.auth.callback.PasswordCallback;
import com.alibaba.druid.util.DruidPasswordCallback;
/**
 */
@SuppressWarnings("serial")
public class DruidDataSource extends com.alibaba.druid.pool.DruidDataSource {
  public PhysicalConnectionInfo createPhysicalConnection() throws SQLException {
    String url = this.getUrl();
    Properties connectProperties = getConnectProperties();
    String user;
    if (getUserCallback() != null) {
      user = getUserCallback().getName();
    } else {
      user = getUsername();
    }
    //DES decryption user = DESUtils.getDecryptString(user);
    String password = DESUtils.getDecryptString(getPassword());
    PasswordCallback passwordCallback = getPasswordCallback();
    if (passwordCallback != null) {
      if (passwordCallback instanceof DruidPasswordCallback) {
        DruidPasswordCallback druidPasswordCallback = (DruidPasswordCallback) passwordCallback;
        druidPasswordCallback.setUrl(url);
        druidPasswordCallback.setProperties(connectProperties);
      }
      char[] chars = passwordCallback.getPassword();
      if (chars != null) {
        password = new String(chars);
      }
    }
    Properties physicalConnectProperties = new Properties();
    if (connectProperties != null) {
      physicalConnectProperties.putAll(connectProperties);
    }
    if (user != null && user.length() != 0) {
      physicalConnectProperties.put("user", user);
    }
    if (password != null && password.length() != 0) {
      physicalConnectProperties.put("password", password);
    }
    Connection conn;
    long connectStartNanos = System.nanoTime();
    long connectedNanos, initedNanos, validatedNanos;
    try {
      conn = createPhysicalConnection(url, physicalConnectProperties);
      connectedNanos = System.nanoTime();
      if (conn == null) {
        throw new SQLException("connect error, url " + url + ", driverClass " + this.driverClass);
      }
      initPhysicalConnection(conn);
      initedNanos = System.nanoTime();
      validateConnection(conn);
      validatedNanos = System.nanoTime();
      setCreateError(null);
    } catch (SQLException ex) {
      setCreateError(ex);
      throw ex;
    } catch (RuntimeException ex) {
      setCreateError(ex);
      throw ex;
    } catch (Error ex) {
      createErrorCount.incrementAndGet();
      throw ex;
    finally
      long nano = System.nanoTime() - connectStartNanos;
      createTimespan += nano;
    }
    return new PhysicalConnectionInfo(conn, connectStartNanos, connectedNanos, initedNanos, validatedNanos);
  }
}

Modify the database connection number configuration of the spring-content.xml file

#Before modification<!-- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> -->
#After modification <bean id="dataSource"class="com.thinkgem.jeesite.common.encrypt.DruidDataSource" 
    init-method="init" destroy-method="close">
    <!-- The data source driver class can be omitted. Druid will automatically identify the DriverClass based on the URL by default -->
    <property name="driverClassName" value="${jdbc.driver}" />
    <!-- Basic attributes url, user, password -->
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />

  </bean>

At this point, the database ciphertext configuration connection is complete!

Summarize

The above is the SSM that I introduced to you to realize the MySQL database account and password ciphertext login function. I hope it will be helpful to you. If you have any questions, please leave me a message and I will reply to you in time. I would also like to thank everyone for their support of the 123WORDPRESS.COM website!
If you find this article helpful, please feel free to reprint it and please indicate the source. Thank you!

You may also be interested in:
  • How to install SQL Server Free Edition and connect to the database using SQL Server Management Studio (SSMS)
  • How to copy a database in SQL Server Management Studio (SSMS)
  • SSM framework uploads pictures and saves them to local and database examples
  • Detailed explanation of printing logs in combination with log4j and slf4j under the SSM framework
  • How to configure LOG4J log in SSM project
  • Configuration details of Log4j logging in SSM integration
  • Detailed explanation of the process of SSM framework saving log information to the database

<<:  How to customize Docker images using Dockerfile

>>:  Node.js makes a simple crawler case tutorial

Recommend

Teach you how to install mysql database on Mac

Download MySQL for Mac: https://downloads.mysql.c...

CSS achieves footer "bottom absorption" effect

We often encounter this problem: how to use CSS t...

Discussion on the way to open website hyperlinks

A new window opens. Advantages: When the user cli...

Case study of dynamic data binding of this.$set in Vue

I feel that the explanation of this.$set on the I...

jQuery simulates picker to achieve sliding selection effect

This article shares the specific code of jQuery t...

SQL implementation of LeetCode (197. Rising temperature)

[LeetCode] 197.Rising Temperature Given a Weather...

Example of how to implement keepalived+nginx high availability

1. Introduction to keepalived Keepalived was orig...

Zabbix's psk encryption combined with zabbix_get value

Since Zabbix version 3.0, it has supported encryp...

How to use dl(dt,dd), ul(li), ol(li) in HTML

HTML <dl> Tag #Definition and Usage The <...

JavaScript to implement the back to top button

This article shares the specific code for JavaScr...

How to create and run a Django project in Ubuntu 16.04 under Python 3

Step 1: Create a Django project Open the terminal...

IDEA graphic tutorial on configuring Tomcat server and publishing web projects

1. After creating the web project, you now need t...

TypeScript uses vscode to monitor the code compilation process

Install Install ts command globally npm install -...