Commit 1db65304 by 郑冰晶

数据库加密组件

parent f35eec17
...@@ -7,30 +7,26 @@ spring: ...@@ -7,30 +7,26 @@ spring:
secooActivityDB: secooActivityDB:
t_price_rule_task: t_price_rule_task:
creator: creator:
cipherColumn: creator
encryptKey: 123 encryptKey: 123
encryptType: AES encryptType: AES
logicColumn: creator
plainColumn: creator plainColumn: creator
cipherColumn: creator
modifior: modifior:
cipherColumn: modifior
encryptKey: 123 encryptKey: 123
encryptType: AES encryptType: AES
logicColumn: modifior
plainColumn: modifior plainColumn: modifior
cipherColumn: modifior
t_smart_batch: t_smart_batch:
creator: creator:
cipherColumn: creator
encryptKey: 456 encryptKey: 456
encryptType: AES encryptType: AES
logicColumn: creator
plainColumn: creator plainColumn: creator
cipherColumn: creator
modifior: modifior:
cipherColumn: modifior
encryptKey: 456 encryptKey: 456
encryptType: AES encryptType: AES
logicColumn: modifior
plainColumn: modifior plainColumn: modifior
cipherColumn: modifior
server: server:
......
package com.secoo.mall.datasource.security.algorithm;
import com.secoo.mall.datasource.security.spi.TypedSPI;
public interface SecurityAlgorithm extends TypedSPI {
}
package com.secoo.mall.datasource.security.algorithm;
public interface SecurityAlgorithmPostProcessor {
void init();
}
...@@ -24,6 +24,11 @@ public final class AESEncryptAlgorithm implements EncryptAlgorithm { ...@@ -24,6 +24,11 @@ public final class AESEncryptAlgorithm implements EncryptAlgorithm {
private byte[] secretKey; private byte[] secretKey;
@Override @Override
public void init(){
this.secretKey = createSecretKey();
}
@Override
public String encrypt(final Object plaintext) throws GeneralSecurityException { public String encrypt(final Object plaintext) throws GeneralSecurityException {
if (null == plaintext) { if (null == plaintext) {
return null; return null;
...@@ -46,11 +51,6 @@ public final class AESEncryptAlgorithm implements EncryptAlgorithm { ...@@ -46,11 +51,6 @@ public final class AESEncryptAlgorithm implements EncryptAlgorithm {
return EncryptType.AES; return EncryptType.AES;
} }
@Override
public void init(){
this.secretKey = createSecretKey();
}
public Properties getProps() { public Properties getProps() {
return this.props; return this.props;
} }
......
package com.secoo.mall.datasource.security.algorithm.encrypt; package com.secoo.mall.datasource.security.algorithm.encrypt;
import com.secoo.mall.datasource.security.spi.TypedSPI; import com.secoo.mall.datasource.security.algorithm.SecurityAlgorithm;
import com.secoo.mall.datasource.security.algorithm.SecurityAlgorithmPostProcessor;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
/** /**
* Encrypt|decrypt algorithm for SPI. * Encrypt|decrypt algorithm for SPI.
*/ */
public interface EncryptAlgorithm extends TypedSPI { public interface EncryptAlgorithm extends SecurityAlgorithm, SecurityAlgorithmPostProcessor {
String ENCRYPT_KEY = "encrypt-key-value"; String ENCRYPT_KEY = "encrypt-key-value";
void init();
/** /**
* Encode. * Encode.
* *
......
package com.secoo.mall.datasource.security.algorithm.encrypt;
import com.secoo.mall.datasource.security.exception.SecurityBizException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Properties;
/**
* RC4 encrypt algorithm.
*/
public class RC4EncryptAlgorithm implements EncryptAlgorithm {
private Properties props = new Properties();
private static final int SBOX_LENGTH = 256;
private static final int KEY_MIN_LENGTH = 5;
private byte[] key = new byte[SBOX_LENGTH - 1];
private int[] sBox = new int[SBOX_LENGTH];
@Override
public void init() {
reset();
setKey(StringUtils.getBytesUtf8(props.getProperty(ENCRYPT_KEY)));
}
@Override
public String encrypt(Object plainText) throws GeneralSecurityException {
if (null == plainText) {
return null;
}
byte[] result = handle(StringUtils.getBytesUtf8(String.valueOf(plainText)), key);
return Base64.encodeBase64String(result);
}
@Override
public String decrypt(String cipherText) throws GeneralSecurityException {
if (null == cipherText) {
return null;
}
byte[] result = handle(Base64.decodeBase64(cipherText), key);
return new String(result, StandardCharsets.UTF_8);
}
@Override
public String getType() {
return null;
}
@Override
public Properties getProps() {
return props;
}
@Override
public void setProps(Properties props) {
this.props = props;
}
private byte[] handle(final byte[] data, final byte[] key) {
reset();
setKey(key);
byte[] result = crypt(data);
reset();
return result;
}
private void reset() {
Arrays.fill(key, (byte) 0);
Arrays.fill(sBox, 0);
}
/**
* Crypt given byte array. Be aware, that you must init key, before using.
* @param message array to be crypt
* @return byte array
* @see <a href="http://en.wikipedia.org/wiki/RC4#Pseudo-random_generation_algorithm_.28PRGA.29">Pseudo-random generation algorithm</a>
*/
private byte[] crypt(final byte[] message) {
sBox = initSBox(key);
byte[] result = new byte[message.length];
int i = 0;
int j = 0;
for (int n = 0; n < message.length; n++) {
i = (i + 1) % SBOX_LENGTH;
j = (j + sBox[i]) % SBOX_LENGTH;
swap(i, j, sBox);
int rand = sBox[(sBox[i] + sBox[j]) % SBOX_LENGTH];
result[n] = (byte) (rand ^ message[n]);
}
return result;
}
/**
* Initialize SBOX with given key, Key-scheduling algorithm.
*
* @param key key
* @return sBox int array
* @see <a href="http://en.wikipedia.org/wiki/RC4#Key-scheduling_algorithm_.28KSA.29">Wikipedia. Init sBox</a>
*/
private int[] initSBox(final byte[] key) {
int[] result = new int[SBOX_LENGTH];
int j = 0;
for (int i = 0; i < SBOX_LENGTH; i++) {
result[i] = i;
}
for (int i = 0; i < SBOX_LENGTH; i++) {
j = (j + result[i] + (key[i % key.length]) & 0xFF) % SBOX_LENGTH;
swap(i, j, result);
}
return result;
}
private void swap(final int i, final int j, final int[] sBox) {
int temp = sBox[i];
sBox[i] = sBox[j];
sBox[j] = temp;
}
/**
* Set key.
*
* @param key key to be setup
* @throws SecurityBizException if key length is smaller than 5 or bigger than 255
*/
private void setKey(final byte[] key) throws SecurityBizException {
if (!(key.length >= KEY_MIN_LENGTH && key.length < SBOX_LENGTH)) {
throw new SecurityBizException("Key length has to be between " + KEY_MIN_LENGTH + " and " + (SBOX_LENGTH - 1));
}
this.key = key;
}
}
...@@ -10,7 +10,7 @@ import com.secoo.mall.datasource.security.config.DataSourceSecurityProperties; ...@@ -10,7 +10,7 @@ import com.secoo.mall.datasource.security.config.DataSourceSecurityProperties;
import com.secoo.mall.datasource.security.constant.PropertyProviderType; import com.secoo.mall.datasource.security.constant.PropertyProviderType;
import com.secoo.mall.datasource.security.constant.SymbolConstants; import com.secoo.mall.datasource.security.constant.SymbolConstants;
import com.secoo.mall.datasource.security.exception.SecurityBizException; import com.secoo.mall.datasource.security.exception.SecurityBizException;
import com.secoo.mall.datasource.security.factory.EncryptAlgorithmFactory; import com.secoo.mall.datasource.security.factory.SecurityAlgorithmFactory;
import com.secoo.mall.datasource.security.rule.ColumnRule; import com.secoo.mall.datasource.security.rule.ColumnRule;
import com.secoo.mall.datasource.security.rule.DbRule; import com.secoo.mall.datasource.security.rule.DbRule;
import com.secoo.mall.datasource.security.rule.TableRule; import com.secoo.mall.datasource.security.rule.TableRule;
...@@ -119,7 +119,7 @@ public class ApolloPropertyProviderAlgorithm implements PropertyProviderAlgorith ...@@ -119,7 +119,7 @@ public class ApolloPropertyProviderAlgorithm implements PropertyProviderAlgorith
} }
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty(EncryptAlgorithm.ENCRYPT_KEY,columnRule.getEncryptKey()); properties.setProperty(EncryptAlgorithm.ENCRYPT_KEY,columnRule.getEncryptKey());
EncryptAlgorithm encryptAlgorithm = EncryptAlgorithmFactory.getObject(columnRule.getEncryptType().toLowerCase(), properties); EncryptAlgorithm encryptAlgorithm = SecurityAlgorithmFactory.getObject(EncryptAlgorithm.class,columnRule.getEncryptType().toLowerCase(), properties);
encryptAlgorithm.init(); encryptAlgorithm.init();
columnRule.setEncryptAlgorithm(encryptAlgorithm); columnRule.setEncryptAlgorithm(encryptAlgorithm);
...@@ -153,6 +153,11 @@ public class ApolloPropertyProviderAlgorithm implements PropertyProviderAlgorith ...@@ -153,6 +153,11 @@ public class ApolloPropertyProviderAlgorithm implements PropertyProviderAlgorith
return PropertyProviderType.APOLLO; return PropertyProviderType.APOLLO;
} }
@Override
public void init() {
}
public static void main(String[] args) { public static void main(String[] args) {
// String x = "a-b-c"; // String x = "a-b-c";
// System.out.println(JSON.toJSONString(x.split("-",2))); // System.out.println(JSON.toJSONString(x.split("-",2)));
......
package com.secoo.mall.datasource.security.algorithm.property; package com.secoo.mall.datasource.security.algorithm.property;
import com.secoo.mall.datasource.security.algorithm.SecurityAlgorithm;
import com.secoo.mall.datasource.security.algorithm.SecurityAlgorithmPostProcessor;
import com.secoo.mall.datasource.security.config.DataSourceSecurityProperties; import com.secoo.mall.datasource.security.config.DataSourceSecurityProperties;
import com.secoo.mall.datasource.security.spi.TypedSPI;
/** /**
* Encrypt|decrypt algorithm for SPI. * PropertyProvider algorithm for SPI.
*/ */
public interface PropertyProviderAlgorithm extends TypedSPI { public interface PropertyProviderAlgorithm extends SecurityAlgorithm, SecurityAlgorithmPostProcessor {
DataSourceSecurityProperties load(); DataSourceSecurityProperties load();
} }
......
package com.secoo.mall.datasource.security.constant; package com.secoo.mall.datasource.security.constant;
public class EncryptType { public class EncryptType {
public static final String DES = "des";
public static final String AES = "aes"; public static final String AES = "aes";
public static final String RC4 = "rc4";
} }
package com.secoo.mall.datasource.security.factory;
import com.secoo.mall.datasource.security.algorithm.property.PropertyProviderAlgorithm;
import com.secoo.mall.datasource.security.spi.SecurityServiceLoader;
import com.secoo.mall.datasource.security.spi.TypedSPIRegistry;
import java.util.Properties;
public class PropertyProviderAlgorithmFactory {
static {
SecurityServiceLoader.register(PropertyProviderAlgorithm.class);
}
public static PropertyProviderAlgorithm getObject(String type, Properties props) {
return TypedSPIRegistry.getRegisteredService(PropertyProviderAlgorithm.class, type, props);
}
}
package com.secoo.mall.datasource.security.factory; package com.secoo.mall.datasource.security.factory;
import com.secoo.mall.datasource.security.algorithm.SecurityAlgorithm;
import com.secoo.mall.datasource.security.algorithm.SecurityAlgorithmPostProcessor;
import com.secoo.mall.datasource.security.algorithm.encrypt.EncryptAlgorithm; import com.secoo.mall.datasource.security.algorithm.encrypt.EncryptAlgorithm;
import com.secoo.mall.datasource.security.algorithm.property.PropertyProviderAlgorithm;
import com.secoo.mall.datasource.security.spi.SecurityServiceLoader; import com.secoo.mall.datasource.security.spi.SecurityServiceLoader;
import com.secoo.mall.datasource.security.spi.TypedSPIRegistry; import com.secoo.mall.datasource.security.spi.TypedSPIRegistry;
import java.util.Properties; import java.util.Properties;
public class EncryptAlgorithmFactory { public class SecurityAlgorithmFactory {
static { static {
SecurityServiceLoader.register(EncryptAlgorithm.class); SecurityServiceLoader.register(EncryptAlgorithm.class);
SecurityServiceLoader.register(PropertyProviderAlgorithm.class);
} }
public static EncryptAlgorithm getObject(String type, Properties props) { @SuppressWarnings("unchecked")
return TypedSPIRegistry.getRegisteredService(EncryptAlgorithm.class, type, props); public static <T extends SecurityAlgorithm> T getObject(final Class<? extends SecurityAlgorithm> algorithmClass,String type, Properties props) {
T result = (T) TypedSPIRegistry.getRegisteredService(algorithmClass, type, props);
if (result instanceof SecurityAlgorithmPostProcessor) {
((SecurityAlgorithmPostProcessor) result).init();
}
return result;
} }
} }
...@@ -524,7 +524,7 @@ public class SecurityFilter extends FilterEventAdapter { ...@@ -524,7 +524,7 @@ public class SecurityFilter extends FilterEventAdapter {
Map<String, ColumnRule> columnRuleMap = new HashMap<>(); Map<String, ColumnRule> columnRuleMap = new HashMap<>();
for(ColumnRule columnRule:tableRule.getColumnRules()){ for(ColumnRule columnRule:tableRule.getColumnRules()){
columnRuleMap.put(columnRule.getLogicColumn(),columnRule); columnRuleMap.put(columnRule.getCipherColumn(),columnRule);
} }
tableRuleMap.put(tableRule.getTableName(),columnRuleMap); tableRuleMap.put(tableRule.getTableName(),columnRuleMap);
......
...@@ -5,7 +5,7 @@ import com.secoo.mall.datasource.security.algorithm.property.PropertyProviderAlg ...@@ -5,7 +5,7 @@ import com.secoo.mall.datasource.security.algorithm.property.PropertyProviderAlg
import com.secoo.mall.datasource.security.config.DataSourceSecurityProperties; import com.secoo.mall.datasource.security.config.DataSourceSecurityProperties;
import com.secoo.mall.datasource.security.constant.PropertyProviderType; import com.secoo.mall.datasource.security.constant.PropertyProviderType;
import com.secoo.mall.datasource.security.exception.SecurityBizException; import com.secoo.mall.datasource.security.exception.SecurityBizException;
import com.secoo.mall.datasource.security.factory.PropertyProviderAlgorithmFactory; import com.secoo.mall.datasource.security.factory.SecurityAlgorithmFactory;
import com.secoo.mall.datasource.security.rule.DbRule; import com.secoo.mall.datasource.security.rule.DbRule;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -41,7 +41,7 @@ public class SecurityFilterContext { ...@@ -41,7 +41,7 @@ public class SecurityFilterContext {
if(StringUtils.isBlank(propertyProvider)){ if(StringUtils.isBlank(propertyProvider)){
propertyProvider =DEFAULT_PROPERTY_PROVIDER; propertyProvider =DEFAULT_PROPERTY_PROVIDER;
} }
PropertyProviderAlgorithm propertyProviderAlgorithm = PropertyProviderAlgorithmFactory.getObject(propertyProvider,new Properties()); PropertyProviderAlgorithm propertyProviderAlgorithm = SecurityAlgorithmFactory.getObject(PropertyProviderAlgorithm.class,propertyProvider,new Properties());
DataSourceSecurityProperties dataSourceSecurityProperties = propertyProviderAlgorithm.load(); DataSourceSecurityProperties dataSourceSecurityProperties = propertyProviderAlgorithm.load();
if(dataSourceSecurityProperties == null){ if(dataSourceSecurityProperties == null){
log.error("!!! Can not find security rules !!!"); log.error("!!! Can not find security rules !!!");
......
...@@ -12,10 +12,6 @@ public class ColumnRule { ...@@ -12,10 +12,6 @@ public class ColumnRule {
*/ */
private String encryptKey; private String encryptKey;
/** /**
* 逻辑字段名称
*/
private String logicColumn;
/**
* 明文字段名称 * 明文字段名称
*/ */
private String plainColumn; private String plainColumn;
...@@ -45,14 +41,6 @@ public class ColumnRule { ...@@ -45,14 +41,6 @@ public class ColumnRule {
this.encryptKey = encryptKey; this.encryptKey = encryptKey;
} }
public String getLogicColumn() {
return logicColumn;
}
public void setLogicColumn(String logicColumn) {
this.logicColumn = logicColumn;
}
public String getPlainColumn() { public String getPlainColumn() {
return plainColumn; return plainColumn;
} }
...@@ -82,7 +70,6 @@ public class ColumnRule { ...@@ -82,7 +70,6 @@ public class ColumnRule {
return "ColumnRule{" + return "ColumnRule{" +
"encryptType='" + encryptType + '\'' + "encryptType='" + encryptType + '\'' +
", encryptKey='" + encryptKey + '\'' + ", encryptKey='" + encryptKey + '\'' +
", logicColumn='" + logicColumn + '\'' +
", plainColumn='" + plainColumn + '\'' + ", plainColumn='" + plainColumn + '\'' +
", cipherColumn='" + cipherColumn + '\'' + ", cipherColumn='" + cipherColumn + '\'' +
", encryptAlgorithm=" + encryptAlgorithm + ", encryptAlgorithm=" + encryptAlgorithm +
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment