0, desensitization rules
1. Environment construction
Create a Spring Boot project and introduce the following dependencies:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.zwqh</groupId>
<artifactId>Sharding - sphere - 4.4.1</artifactId>
<version>1.0 the SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.zwqh</groupId>
<artifactId>sharding-sphere-demo-8</artifactId>
<version>${parent.version}</version>
<packaging>jar</packaging>
<name>sharding-sphere-demo-8</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>cn.zwqh.shardingspheredemo8.ShardingSphereDemo8Application</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Copy the code
1.2 Test database DS1
CREATE TABLE `t_user` (
`user_id` int NOT NULL COMMENT 'user id',
`user_name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT User name,
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'Password plaintext',
`password_encrypt` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'Cipher text',
`password_assisted` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'Auxiliary query column'.PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
Copy the code
1.3. Entity classes
@Data
public class UserEntity {
private Integer userId;
private String userName;
private String password;
private String passwordEncrypt;
private String passwordAssisted;
}
Copy the code
1.4, Mapper
@Mapper
public interface UserMapper {
@Insert("insert into t_user(user_id,user_name,password) values(#{userId},#{userName},#{password})")
void insertUser(UserEntity userEntity);
@Select("select * from t_user where user_name=#{userName} and password=#{password}")
@Results({ @Result(column = "user_id", property = "userId"), @Result(column = "user_name", property = "userName"), @Result(column = "password", property = "password"), @Result(column = "password_assisted", property = "passwordAssisted") })
List<UserEntity> getUserInfo(@Param("userName") String userName, @Param("password") String password);
}
Copy the code
1.5. Test class
@Slf4j
@SpringBootTest
class ShardingSphereDemo8ApplicationTests {
@Resource
private UserMapper userMapper;
@Test
void insertUser(a) {
UserEntity userEntity = new UserEntity();
userEntity.setUserId(19);
userEntity.setUserName("user19");
userEntity.setPassword("123456");
userMapper.insertUser(userEntity);
}
@Test
void getUserInfo(a) {
List<UserEntity> userEntityList = userMapper.getUserInfo("user19"."123456"); log.info(userEntityList.toString()); }}Copy the code
2. Default encryption algorithm
2.1, AES
The configuration file
# Application name
spring.application.name=sharding-sphere-demo-8
spring.shardingsphere.datasource.name=ds
spring.shardingsphere.datasource.ds.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds.url=JDBC: mysql: / / 127.0.0.1:3306 / ds1? serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=123456
spring.shardingsphere.datasource.ds.max-total=100
Use AES symmetric encryption policy
spring.shardingsphere.encrypt.encryptors.encryptor_aes.type=aes
spring.shardingsphere.encrypt.encryptors.encryptor_aes.props.aes.key.value=123456
# password is a logical column, password is a data display column, and password_encrypt is a data table ciphertext column
spring.shardingsphere.encrypt.tables.t_user.columns.password.plainColumn=password
spring.shardingsphere.encrypt.tables.t_user.columns.password.cipherColumn=password_encrypt
spring.shardingsphere.encrypt.tables.t_user.columns.password.encryptor=encryptor_aes
spring.shardingsphere.props.sql.show=true
# Query whether ciphertext columns are used
spring.shardingsphere.props.query.with.cipher.column=true
Copy the code
The test results
1. The logical column is changed to the plaintext column and the ciphertext column when the logical column is added
2, only set the plaintext column, run direct error, so must set encryption column
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'encryptDataSource' defined in class path resource [org/apache/shardingsphere/shardingjdbc/spring/boot/SpringBootConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'encryptDataSource' threw exception; nested exception is java.lang.IllegalArgumentException: Invalid encrypt column configurations in EncryptTableRuleConfigurations.
Copy the code
3. Set only the ciphertext column. If the operation succeeds, the plaintext column is encrypted and the database is actually inserted into the ciphertext column
4, set the plaintext and ciphertext columns, spring. Shardingsphere. Props. Query. With. The cipher. The column to false, the query by included, return data is included
5, set the plaintext and ciphertext columns, spring. Shardingsphere. Props. Query. With. The cipher, the column is true, the query by cipher text query, return the data is clear
6, set the cipher text columns, only spring. Shardingsphere. Props. Query. With. The cipher. The column to false, the default through the cipher text query, query but not into the parameter automatically encrypted, so can’t check the data
7, set the cipher text columns, only spring. Shardingsphere. Props. Query. With. The cipher, the column is true, the query by cipher text query, return the data is clear
2.2, MD5
The configuration file
# Application name
spring.application.name=sharding-sphere-demo-8
spring.shardingsphere.datasource.name=ds
spring.shardingsphere.datasource.ds.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds.url=JDBC: mysql: / / 127.0.0.1:3306 / ds1? serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=123456
spring.shardingsphere.datasource.ds.max-total=100
# Use MD5 encryption policy
spring.shardingsphere.encrypt.encryptors.encryptor_md5.type=MD5
# password is a logical column, password is a data display column, and password_encrypt is a data table ciphertext column
spring.shardingsphere.encrypt.tables.t_user.columns.password.plainColumn=password
spring.shardingsphere.encrypt.tables.t_user.columns.password.cipherColumn=password_encrypt
spring.shardingsphere.encrypt.tables.t_user.columns.password.encryptor=encryptor_md5
spring.shardingsphere.props.sql.show=true
# Query whether ciphertext columns are used
spring.shardingsphere.props.query.with.cipher.column=true
Copy the code
The test results
1. When adding data, you can see that the encrypted data is different from the AES data
2, query, spring. Shardingsphere. Props. Query. With. Cipher. The column is true, through the cipher text query, because the MD5 encryption is symmetrical, so return the cipher text data
3, query, spring. Shardingsphere. Props. Query. With. Cipher. The column to false, by included a query, return to clear data
3. SPI custom encryption algorithm
3.1 SPI configuration
Add a new configuration in the resources/ meta-INF /services directory
The configuration file name is: the org. Apache. Shardingsphere. Encrypt. Strategy. Spi. The Encryptor
The contents of the configuration file, the full path of the class where the custom encryption policy is placed, and the full path of the class where the official built-in encryption policy is to be used
org.apache.shardingsphere.encrypt.strategy.impl.AESEncryptor
org.apache.shardingsphere.encrypt.strategy.impl.MD5Encryptor
cn.zwqh.shardingspheredemo8.encryptor.Sha256Encryptor
cn.zwqh.shardingspheredemo8.encryptor.Sha256RandomEncryptor
Copy the code
Implement the Encryptor interface
Create Sha256Encryptor class
@Getter
@Setter
public class Sha256Encryptor implements Encryptor {
private Properties properties = new Properties();
@Override
public void init(a) {}@Override
public String encrypt(Object plaintext) {
if (null == plaintext) {
return null;
}
return DigestUtils.sha256Hex(String.valueOf(plaintext));
}
@Override
public Object decrypt(String ciphertext) {
return ciphertext;
}
@Override
public String getType(a) {
return "SHA256"; }}Copy the code
Modifying a Configuration File
# Application name
spring.application.name=sharding-sphere-demo-8
spring.shardingsphere.datasource.name=ds
spring.shardingsphere.datasource.ds.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds.url=JDBC: mysql: / / 127.0.0.1:3306 / ds1? serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=123456
spring.shardingsphere.datasource.ds.max-total=100
# Use custom policy SHA256
spring.shardingsphere.encrypt.encryptors.encryptor_sha256.type=SHA256
# password is a logical column, password is a data display column, and password_encrypt is a data table ciphertext column
spring.shardingsphere.encrypt.tables.t_user.columns.password.plainColumn=password
spring.shardingsphere.encrypt.tables.t_user.columns.password.cipherColumn=password_encrypt
spring.shardingsphere.encrypt.tables.t_user.columns.password.encryptor=encryptor_sha256
spring.shardingsphere.props.sql.show=true
# Query whether ciphertext columns are used
spring.shardingsphere.props.query.with.cipher.column=true
Copy the code
The test results
1. If the encrypted data is different from the AES data, the user-defined encryption policy is successfully used
2, query, spring. Shardingsphere. Props. Query. With. Cipher. The column is true, through the cipher text query, due to similar SHA256 MD5 encryption, so return the cipher text data
3, query, spring. Shardingsphere. Props. Query. With. Cipher. The column to false, by included a query, return to clear data
Implement QueryAssistedEncryptor interface
Create Sha256RandomEncryptor class
@Getter
@Setter
public class Sha256RandomEncryptor implements QueryAssistedEncryptor {
private Properties properties = new Properties();
@Override
public String queryAssistedEncrypt(String plaintext) {
if (null == plaintext) {
return null;
}
// Raw string
return DigestUtils.sha256Hex(String.valueOf(plaintext));
}
@Override
public void init(a) {}@Override
public String encrypt(Object plaintext) {
if (null == plaintext) {
return null;
}
// Raw string + change factor (such as timestamp)
plaintext = plaintext.toString() + LocalDateTime.now().toString();
return DigestUtils.sha256Hex(String.valueOf(plaintext));
}
@Override
public Object decrypt(String ciphertext) {
return ciphertext;
}
@Override
public String getType(a) {
return "SHA256_RANDOM"; }}Copy the code
Modifying a Configuration File
# Application name
spring.application.name=sharding-sphere-demo-8
spring.shardingsphere.datasource.name=ds
spring.shardingsphere.datasource.ds.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds.url=JDBC: mysql: / / 127.0.0.1:3306 / ds1? serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=123456
spring.shardingsphere.datasource.ds.max-total=100
# Use custom policy SHA256_RANDOM
spring.shardingsphere.encrypt.encryptors.encryptor_sha256_random.type=SHA256_RANDOM
# password is the logical column, password is the data display column, password_ENCRYPT is the data table ciphertext column, and password_assisted query column
spring.shardingsphere.encrypt.tables.t_user.columns.password.plainColumn=password
spring.shardingsphere.encrypt.tables.t_user.columns.password.cipherColumn=password_encrypt
spring.shardingsphere.encrypt.tables.t_user.columns.password.assistedQueryColumn=password_assisted
spring.shardingsphere.encrypt.tables.t_user.columns.password.encryptor=encryptor_sha256_random
spring.shardingsphere.props.sql.show=true
# Query whether ciphertext columns are used
spring.shardingsphere.props.query.with.cipher.column=true
Copy the code
The test results
1. Add two user data with the same password. You can see that the data in the ciphertext column is inconsistent, and the data in the secondary column is consistent, which can better protect the data security
2, query, spring. Shardingsphere. Props. Query. With. Cipher. The column is true, through assisted query query, and returns the data for the cipher text columns
3, query, spring. Shardingsphere. Props. Query. With. Cipher. The column to false, by included a query, and the data returned is clear
The source code
github
Yards cloud
summary
1. The default data encryption algorithm supports AES and MD5. AES is symmetric encryption and MD5 is asymmetric encryption.
2. You can customize the encryption policy through SPI;
3. Select and configure an appropriate encryption algorithm based on service security requirements.
Link: www.zwqh.top/article/inf…