Springboot项目对数据库用户名密码实现加密过程解析

下面是关于SpringBoot项目对数据库用户名密码实现加密过程解析的攻略:

1. 加密方式

SpringBoot项目对数据库用户名密码实现加密的方式是通过在配置文件application.properties中配置数据源时设置加密方式来实现。

目前SpringBoot支持多种加密方式,包括对称加密和非对称加密。其中,对称加密是指加解密都使用同一个密钥的加密方式,可以实现简单的加解密操作;非对称加密则是指加解密使用不同的密钥对,具有更高的安全性。

常见的对称加密算法有DES、AES等;非对称加密算法有RSA等。这里以AES加密算法为例进行讲解。

2. 加密过程

  1. 在application.properties文件中添加加密方式和密钥设置:

    ```
    spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useSSL=false
    spring.datasource.username=ENC(用户名)
    spring.datasource.password=ENC(加密后的密码)
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver

    配置加密方式和密钥

    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.druid.initial-size=1
    spring.datasource.druid.max-active=20
    spring.datasource.druid.min-idle=1
    spring.datasource.druid.test-on-borrow=true
    spring.datasource.druid.test-on-return=true
    spring.datasource.druid.test-while-idle=true
    spring.datasource.druid.time-between-eviction-runs-millis=60000
    spring.datasource.druid.validation-query=select 1 from dual
    spring.datasource.druid.filters=stat
    spring.datasource.publicKey=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIiw1FXOgmdvQQd57CIia7rIiHE4w5FXW0HIFGkONcd42F0c+G90P+K+yU7W/7jNnqFYoTuZ+Um+WYJy8APWzECAwEAAQ==
    spring.datasource.connection-properties=druid.stat.slowSqlMillis=5000;druid.stat.logSlowSql=true;druid.stat.mergeSql=true;druid.stat.slowSqlWallMillis=10000;druid.stat.logSql=true;druid.stat.slowSqlMaxSize=10
    ```

    其中,"ENC(用户名)"和"ENC(加密后的密码)"表示将该值进行加密,并在配置文件中存储加密后的字符串。使用加密方式前,需要先提供一个公钥用于对密码进行加密和对加密后的密码进行解密,可以使用如下方法生成公钥:

    java
    @Test
    public void testEncryptionUtil() {
    EncryptionUtil encryptionUtil = new EncryptionUtil();
    encryptionUtil.initKey();
    System.out.println("公钥: " + encryptionUtil.getPublicKey());
    }

    生成公钥后将其配置到application.properties中的spring.datasource.publicKey属性中。

  2. 编写EncryptionUtil类,用于生成公钥,并进行加密和解密操作:

    ``` java
    @Slf4j
    public class EncryptionUtil {

    /**
     * 非对称加密算法
     **/
    public static final String KEY_ALGORITHM = "RSA";
    
    /**
     * 算法名称/加密模式/填充方式
     **/
    public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
    
    /**
     * 密钥长度,用来初始化
     **/
    public static final int KEY_SIZE = 1024;
    
    /**
     * 随机数生成器
     **/
    private static final SecureRandom RANDOM = new SecureRandom();
    
    private KeyPair keyPair;
    
    /**
     * 生成公钥和私钥
     */
    public void initKey() {
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            keyPairGen.initialize(KEY_SIZE, RANDOM);
            this.keyPair = keyPairGen.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            log.error("初始化密钥对失败", e);
        }
    }
    
    /**
     * 加密数据
     *
     * @param data      待加密数据
     * @param publicKey 公钥
     * @return 加密后的数据
     */
    public String encrypt(byte[] data, String publicKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(publicKey.getBytes());
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey key = keyFactory.generatePublic(keySpec);
        // 得到Cipher对象来实现对源数据的RSA加密
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] resultBytes = cipher.doFinal(data);
        return Base64.encodeBase64String(resultBytes);
    }
    
    /**
     * 解密数据
     *
     * @param data       待解密数据
     * @param privateKey 私钥
     * @return 解密后的字节数组
     */
    public byte[] decrypt(String data, String privateKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes());
        // 构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        // 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        // 取私钥匙对象
        PrivateKey key = keyFactory.generatePrivate(keySpec);
        // 对数据解密
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(Base64.decodeBase64(data.getBytes()));
    }
    
    /**
     * 读取公钥
     *
     * @param publicKeyFile 公钥文件路径
     * @return 公钥
     * @throws Exception 异常
     */
    public static String readPublicKey(String publicKeyFile) throws Exception {
        FileReader fileReader = new FileReader(publicKeyFile);
        BufferedReader in = new BufferedReader(fileReader);
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        return sb.toString();
    }
    
    /**
     * 获取公钥字符串
     *
     * @return 公钥字符串
     */
    public String getPublicKey() {
        return Base64.encodeBase64String(this.keyPair.getPublic().getEncoded());
    }
    
    /**
     * 获取私钥字符串
     *
     * @return 私钥字符串
     */
    public String getPrivateKey() {
        return Base64.encodeBase64String(this.keyPair.getPrivate().getEncoded());
    }
    

    }
    ```

  3. 加密过程示例:

    java
    @Test
    public void testEncrypt() throws Exception {
    EncryptionUtil encryptionUtil = new EncryptionUtil();
    encryptionUtil.initKey();
    String publicKey = encryptionUtil.getPublicKey();
    String password = "123456";
    String encryptedPassword = encryptionUtil.encrypt(password.getBytes(), publicKey);
    System.out.println("加密后的密码:" + encryptedPassword);
    }

    运行结果如下:

    加密后的密码:xBNuKn1QWrkLxXVIhRCC39tOM3cknfRnhCJ+K1a0x9ZIBK6WM010WCYy9OAwLziyL1W5y42BPN04zeB1JuPKHfYeKYJXX9sSSsU1hW/jlIe6dbqkMlOQmrMz7/c+l/UKlR1dN8SwSBqXjkOfdAb1Rd+NcNDk/vcQReNWmKR2tVY=

    将生成的加密后的密码配置到application.properties中的spring.datasource.password中。

  4. 解密过程示例:

    java
    @Test
    public void testDecrypt() throws Exception {
    String password = "xBNuKn1QWrkLxXVIhRCC39tOM3cknfRnhCJ+K1a0x9ZIBK6WM010WCYy9OAwLziyL1W5y42BPN04zeB1JuPKHfYeKYJXX9sSSsU1hW/jlIe6dbqkMlOQmrMz7/c+l/UKlR1dN8SwSBqXjkOfdAb1Rd+NcNDk/vcQReNWmKR2tVY=";
    String privateKey = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAiLDUVc6CZ29BB3nsIiJrusiIcTjDkVdbQcgUaQ41x3jYXRz4b3Q/4r7JTtb/uM2eoVihO5n5Sb5ZgnLwA9bMQIDAQABAkAtl2TprHhi+jwWEAST5b4emP4I1i/7wQ6CLvVhwrS70DMfi1b/k+cZF3ly56NZCR5bjyTVgcROi6YwBqtI/0ZBAiEA+60tfl93f22Qb4mfpbg92O0ZdJGXWXShy0zvTzMTsMCIQD3F+OBnly+Y7Pd+N6lTw4Cno3tE4Sui9Rn8CLqQDXTwIhANP+xCPf8WrY6tL/DUpftxyQPbz3ZcmGrMizneyT8lPRAiBtK5Tq7gRNJLqfF1yIpcy+Z0yt9Y8EzkiNxHh0TFAxQIgMZNamYALQh3zgtXvfFLnGsWZZbJ/ST2t7E0OywqmCQ=";
    EncryptionUtil encryptionUtil = new EncryptionUtil();
    byte[] decryptedData = encryptionUtil.decrypt(password, privateKey);
    System.out.println("解密后的密码:" + new String(decryptedData));
    }

    运行结果如下:

    解密后的密码:123456

以上就是SpringBoot项目对数据库用户名密码实现加密的完整攻略,从加密方式、加密过程到解密过程都进行了详细讲解,并提供了示例代码。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot项目对数据库用户名密码实现加密过程解析 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • php预定义变量使用帮助(带实例)

    PHP预定义变量使用帮助(带实例) PHP提供了一些预定义变量,它们在不同的上下文中自动设置,并且可以在脚本中直接使用。这些预定义变量提供了有关服务器、请求和其他环境信息的有用信息。在本攻略中,我们将详细介绍一些常用的PHP预定义变量,并提供示例说明。 1. $_SERVER $_SERVER是一个包含了服务器和执行环境信息的关联数组。它提供了许多有用的变量…

    other 2023年8月15日
    00
  • 如何让Nginx支持中文文件名具体设置步骤

    当文件路径或名称中包含特殊字符(如中文、空格等)时,Nginx可能会出现访问失败的问题。为了使Nginx支持中文文件名,需要在配置文件中进行如下设置: 修改配置文件 在Nginx的配置文件中,需要修改http节点下的server节点。找到server节点中的charset设置项,将其设置为utf-8,可以保证nginx可以正确处理中文字符。 同时,在serv…

    other 2023年6月26日
    00
  • GO语言字符串处理Strings包的函数使用示例讲解

    针对“GO语言字符串处理Strings包的函数使用示例讲解”的完整攻略,我会按照以下步骤进行讲解: Strings包简介 Strings包中的常用函数 函数使用示例 示例一:字符串拼接 示例二:字符串切割 Strings包简介 Strings包是GO语言中处理字符串的标准包,包含了一些常用的操作字符串的函数,同时也提供了一些高级的功能,如正则表达式匹配等等。…

    other 2023年6月20日
    00
  • pytorch预测之解决多次预测结果不一致问题

    pytorch预测之解决多次预测结果不一致问题 在使用PyTorch进行神经网络的预测过程中,可能会发现多次预测同一组数据时,模型给出的预测结果会产生不一致的情况。这是由于模型中包含了dropout、随机初始化等随机因素导致的,为了解决这个问题,我们可以采取以下两种方法: 方法一:取消dropout 模型中的dropout层会随机地放弃部分神经元的输出,这是…

    other 2023年6月27日
    00
  • mac环境下python3安装及配置

    Mac环境下Python3安装及配置 Python是一种高级编程语言,广泛应用于Web开发、机器学习、数据分析等领域。在Mac环境下使用Python可以提高工作效率,但需要正确安装及配置Python,下面我们来介绍具体步骤。 步骤一:安装Homebrew Homebrew是Mac下最流行的包管理工具,用于简化软件安装过程。在Terminal中输入以下命令安装…

    其他 2023年3月28日
    00
  • 详解C++ bitset用法

    详解C++ bitset用法 bitset是C++ STL中的一个类,用于位运算。它最主要的作用是用来压缩表示布尔值数组。bitset内部使用一个数组来存储每个位的状态,这个数组通常使用一个整数类型的数组,每个整数通常为一个字长,即32或64位。可以使用位运算符对bitset进行各种操作。 本文将详细讲解bitset的用法,以及两个示例说明。 基本用法 要使…

    other 2023年6月26日
    00
  • oracle(创建视图)

    Oracle – 创建视图 在Oracle数据库中,视图(View)是一种虚拟表,它不存储数据,而是基于一个或多个表的查询结果返回的临时结果集。在查询数据时,视图可以用作查询表的一个代理,它可以简化查询操作,同时保证查询操作的安全性。本文将介绍 Oracle 数据库中如何创建视图。 语法 创建视图的语法如下: CREATE [OR REPLACE] [FOR…

    其他 2023年3月28日
    00
  • Android编程实现自定义PopupMenu样式示例【显示图标与设置RadioButton图标】

    下面我将详细讲解“Android编程实现自定义PopupMenu样式示例【显示图标与设置RadioButton图标】”的完整攻略: 一、自定义PopupMenu样式 创建新的布局文件custom_popup_menu.xml以自定义PopupMenu中item的样式。 <LinearLayout xmlns:android="http://s…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部