• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    SSM实现mysql数据库账号密码密文登录功能

    引言

          咱们公司从事的是信息安全涉密应用的一些项目研发一共有分为三步,相比较于一般公司和一般的项目,对于信息安全要求更加严格,领导要求数据量和用户的用户名及密码信息都必需是要密文配置和存储的,这就涉及到jdbc.properties文件中的数据库的用户名和密码也是一样的,需要配置问密文,在连接的时候再加载解密为明文进行数据库的连接操作,以下就是实现过程,一共有分为三步。

    一、创建DESUtil类

    提供自定义密钥,加密解密的方法。

    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;
      //自己的密钥
      private 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);
        }
      }
      /**
       * 对字符串进行加密,返回BASE64的加密字符串
       *
       * @param str
       * @return
       * @see [类、类#方法、类#成员]
       */
      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);
        }
      }
      /**
       * 对BASE64加密字符串进行解密
       *
       */
      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));
      }
    }

    二、 创建EncryptPropertyPlaceholderConfigurer类

    建立与配置文件的关联。

    package com.hzdy.DCAD.common.util;
    import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
    public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
      //属性需与配置文件的KEY保持一直
      private String[] encryptPropNames = {"jdbc.username", "jdbc.password"};
      @Override
      protected String convertProperty(String propertyName, String propertyValue) {
        //如果在加密属性名单中发现该属性 
        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;
      }
    }

    三、 修改配置文件 jdbc.properties

    #加密配置之前
    #jdbc.driver=com.mysql.jdbc.Driver
    #jdbc.user=root
    #jdbc.password=root
    #jdbc.url=jdbc:mysql://localhost:3306/bookstore
    #加密配置之后
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.user=Ov4j7fKiCzY=
    jdbc.password=Ov4j7fKiCzY=
    jdbc.url=jdbc:mysql://localhost:3306/bookstore

    四、 修改spring-content.xml配置文件

    将spring-context中的
     context:property-placeholder location="classpath:.properties" />
     修改为
     bean class="com.hzdy.DCAD.common.util.EncryptPropertyPlaceholderConfigurer"p:locations="classpath:*.properties"/>
     //注意只能存在一个读取配置文件的bean,否则系统只会读取最前面的

       注意:如果发现配置密文的usernamepassword可以加载并解密成功,但是最后连接的时候还是以密文连接并报错,这可能涉及到内存预加载的问题,项目一启动,程序会加密密文的用户名和密码,就算最后解密成功了,最后连接数据库读取的却还是密文,这时候我们可以自己重写连接池的方法,让spring-content.xml加载重写的连接池方法,并在连接的时候再提前进行解密。

    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解密
        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);
      }
    }

    修改spring-content.xml文件的数据库连接数配置

    #修改之前
    !-- bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> -->
    #修改之后
    bean id="dataSource"class="com.thinkgem.jeesite.common.encrypt.DruidDataSource" 
        init-method="init" destroy-method="close">
        !-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
        property name="driverClassName" value="${jdbc.driver}" />
        !-- 基本属性 url、user、password -->
        property name="url" value="${jdbc.url}" />
        property name="username" value="${jdbc.username}" />
        property name="password" value="${jdbc.password}" />
    
      /bean>

    至此,数据库密文配置连接就完成了!

    总结

    以上所述是小编给大家介绍的SSM实现mysql数据库账号密码密文登录功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
    如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

    您可能感兴趣的文章:
    • SQL Server免费版的安装以及使用SQL Server Management Studio(SSMS)连接数据库的图文方法
    • SQL Server Management Studio(SSMS)复制数据库的方法
    • ssm框架上传图片保存到本地和数据库示例
    • 详解SSM框架下结合log4j、slf4j打印日志
    • SSM项目中配置LOG4J日志的方法
    • SSM整合中的Log4j日志的配置详情
    • SSM框架把日志信息保存到数据库过程详解
    上一篇:mysql定时任务(event事件)实现详解
    下一篇:MYSQL数据库表结构优化方法详解
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    SSM实现mysql数据库账号密码密文登录功能 SSM,实现,mysql,数据库,账号,