fix: 加密属性

This commit is contained in:
wangyu 2021-01-16 11:47:50 +08:00
parent a1f4b2ad31
commit 925cc2945f
6 changed files with 173 additions and 1 deletions

View File

@ -28,5 +28,9 @@
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
</project>

View File

@ -0,0 +1,24 @@
package com.flyfish.framework.annotations;
import com.flyfish.framework.config.DecryptConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* 启用加解密属性
* @author wangyu
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DecryptConfig.class)
public @interface EnablePropertyEncrypt {
/**
* 默认密码
*
* @return 结果
*/
String defaultPassword() default "flyfish-framework";
}

View File

@ -0,0 +1,42 @@
package com.flyfish.framework.config;
import com.flyfish.framework.config.encrypt.AESEncryptablePropertyResolver;
import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter;
import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver;
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.context.annotation.Bean;
/**
* 解密配置
* 沿用datalink优良的安全性
*
* @author wangyu
*/
@AutoConfigureBefore(MongoDataAutoConfiguration.class)
@ConditionalOnProperty("flyfish.jasypt.key")
@EnableEncryptableProperties
public class DecryptConfig {
private static final String PASSWORD_KEY = "password";
/**
* 加密属性解析器
*
* @return 结果
*/
@Bean
public EncryptablePropertyResolver encryptablePropertyResolver(@Value("${flyfish.jasypt.key}") String password) {
return new AESEncryptablePropertyResolver(password);
}
@Bean(name = "encryptablePropertyFilter")
public EncryptablePropertyFilter encryptablePropertyFilter() {
return (source, name) -> StringUtils.endsWithIgnoreCase(name, PASSWORD_KEY);
}
}

View File

@ -0,0 +1,39 @@
package com.flyfish.framework.config.encrypt;
import com.flyfish.framework.utils.HexUtils;
import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver;
import org.apache.commons.lang3.StringUtils;
import org.jasypt.util.binary.AES256BinaryEncryptor;
import java.nio.charset.StandardCharsets;
/**
* 加密处理器
*
* @author wangyu
*/
public class AESEncryptablePropertyResolver implements EncryptablePropertyResolver {
private static final String PREFIX = "$-";
private final AES256BinaryEncryptor encryptor;
public AESEncryptablePropertyResolver(String password) {
this.encryptor = new AES256BinaryEncryptor();
encryptor.setPassword(password);
}
public String encrypt(String password) {
byte[] bytes = password.getBytes(StandardCharsets.UTF_8);
return PREFIX + HexUtils.byteArray2Hex(encryptor.encrypt(bytes));
}
@Override
public String resolvePropertyValue(String value) {
if (StringUtils.isNotBlank(value) && value.startsWith(PREFIX)) {
String encrypted = StringUtils.substringAfter(value, PREFIX);
byte[] bytes = encryptor.decrypt(HexUtils.hex2ByteArray(encrypted));
return new String(bytes, StandardCharsets.UTF_8);
}
return value;
}
}

View File

@ -0,0 +1,57 @@
package com.flyfish.framework.utils;
import java.nio.charset.StandardCharsets;
/**
* byte array和hex string互转
* @author wangyu
*/
public class HexUtils {
/**
* 将byte数组转换为表示16进制值的字符串 byte[]{8,18}转换为0813 和public static byte[]
* hexStr2ByteArr(String strIn) 互为可逆的转换过程
*
* @param bytes 需要转换的byte数组
* @return 转换后的字符串
*/
public static String byteArray2Hex(byte[] bytes) {
int length = bytes.length;
// 每个byte用两个字符才能表示所以字符串的长度是数组长度的两倍
StringBuilder sb = new StringBuilder(length * 2);
for (int b : bytes) {
int temp = b;
// 把负数转换为正数
while (temp < 0) {
temp = temp + 256;
}
// 小于0F的数需要在前面补0
if (temp < 16) {
sb.append("0");
}
sb.append(Integer.toString(temp, 16));
}
return sb.toString();
}
/**
* 将表示16进制值的字符串转换为byte数组 和public static String byteArr2HexStr(byte[] arrB)
* 互为可逆的转换过程
*
* @param hex 需要转换的字符串
* @return 转换后的byte数组
*/
public static byte[] hex2ByteArray(String hex) {
byte[] bytes = hex.getBytes(StandardCharsets.UTF_8);
int length = bytes.length;
// 两个字符表示一个字节所以字节数组长度是字符串长度除以2
byte[] result = new byte[length / 2];
for (int i = 0; i < length; i = i + 2) {
String temp = new String(bytes, i, 2, StandardCharsets.UTF_8);
result[i / 2] = (byte) Integer.parseInt(temp, 16);
}
return result;
}
}

View File

@ -22,6 +22,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jasypt.version>3.0.3</jasypt.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<jjwt.version>0.11.0</jjwt.version>
<reflection.version>0.9.11</reflection.version>
@ -92,6 +93,11 @@
<artifactId>reflections</artifactId>
<version>${reflection.version}</version>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>${jasypt.version}</version>
</dependency>
</dependencies>
</dependencyManagement>