Commit 1db65304 by 郑冰晶

数据库加密组件

parent f35eec17
......@@ -7,30 +7,26 @@ spring:
secooActivityDB:
t_price_rule_task:
creator:
cipherColumn: creator
encryptKey: 123
encryptType: AES
logicColumn: creator
plainColumn: creator
cipherColumn: creator
modifior:
cipherColumn: modifior
encryptKey: 123
encryptType: AES
logicColumn: modifior
plainColumn: modifior
cipherColumn: modifior
t_smart_batch:
creator:
cipherColumn: creator
encryptKey: 456
encryptType: AES
logicColumn: creator
plainColumn: creator
cipherColumn: creator
modifior:
cipherColumn: modifior
encryptKey: 456
encryptType: AES
logicColumn: modifior
plainColumn: modifior
cipherColumn: modifior
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 {
private byte[] secretKey;
@Override
public void init(){
this.secretKey = createSecretKey();
}
@Override
public String encrypt(final Object plaintext) throws GeneralSecurityException {
if (null == plaintext) {
return null;
......@@ -46,11 +51,6 @@ public final class AESEncryptAlgorithm implements EncryptAlgorithm {
return EncryptType.AES;
}
@Override
public void init(){
this.secretKey = createSecretKey();
}
public Properties getProps() {
return this.props;
}
......
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;
/**
* Encrypt|decrypt algorithm for SPI.
*/
public interface EncryptAlgorithm extends TypedSPI {
public interface EncryptAlgorithm extends SecurityAlgorithm, SecurityAlgorithmPostProcessor {
String ENCRYPT_KEY = "encrypt-key-value";
void init();
/**
* 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;
import com.secoo.mall.datasource.security.constant.PropertyProviderType;
import com.secoo.mall.datasource.security.constant.SymbolConstants;
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.DbRule;
import com.secoo.mall.datasource.security.rule.TableRule;
......@@ -119,7 +119,7 @@ public class ApolloPropertyProviderAlgorithm implements PropertyProviderAlgorith
}
Properties properties = new Properties();
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();
columnRule.setEncryptAlgorithm(encryptAlgorithm);
......@@ -153,6 +153,11 @@ public class ApolloPropertyProviderAlgorithm implements PropertyProviderAlgorith
return PropertyProviderType.APOLLO;
}
@Override
public void init() {
}
public static void main(String[] args) {
// String x = "a-b-c";
// System.out.println(JSON.toJSONString(x.split("-",2)));
......
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.spi.TypedSPI;
/**
* Encrypt|decrypt algorithm for SPI.
* PropertyProvider algorithm for SPI.
*/
public interface PropertyProviderAlgorithm extends TypedSPI {
public interface PropertyProviderAlgorithm extends SecurityAlgorithm, SecurityAlgorithmPostProcessor {
DataSourceSecurityProperties load();
}
......
package com.secoo.mall.datasource.security.constant;
public class EncryptType {
public static final String DES = "des";
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;
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.property.PropertyProviderAlgorithm;
import com.secoo.mall.datasource.security.spi.SecurityServiceLoader;
import com.secoo.mall.datasource.security.spi.TypedSPIRegistry;
import java.util.Properties;
public class EncryptAlgorithmFactory {
public class SecurityAlgorithmFactory {
static {
SecurityServiceLoader.register(EncryptAlgorithm.class);
SecurityServiceLoader.register(PropertyProviderAlgorithm.class);
}
public static EncryptAlgorithm getObject(String type, Properties props) {
return TypedSPIRegistry.getRegisteredService(EncryptAlgorithm.class, type, props);
@SuppressWarnings("unchecked")
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 {
Map<String, ColumnRule> columnRuleMap = new HashMap<>();
for(ColumnRule columnRule:tableRule.getColumnRules()){
columnRuleMap.put(columnRule.getLogicColumn(),columnRule);
columnRuleMap.put(columnRule.getCipherColumn(),columnRule);
}
tableRuleMap.put(tableRule.getTableName(),columnRuleMap);
......
......@@ -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.constant.PropertyProviderType;
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 org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
......@@ -41,7 +41,7 @@ public class SecurityFilterContext {
if(StringUtils.isBlank(propertyProvider)){
propertyProvider =DEFAULT_PROPERTY_PROVIDER;
}
PropertyProviderAlgorithm propertyProviderAlgorithm = PropertyProviderAlgorithmFactory.getObject(propertyProvider,new Properties());
PropertyProviderAlgorithm propertyProviderAlgorithm = SecurityAlgorithmFactory.getObject(PropertyProviderAlgorithm.class,propertyProvider,new Properties());
DataSourceSecurityProperties dataSourceSecurityProperties = propertyProviderAlgorithm.load();
if(dataSourceSecurityProperties == null){
log.error("!!! Can not find security rules !!!");
......
......@@ -12,10 +12,6 @@ public class ColumnRule {
*/
private String encryptKey;
/**
* 逻辑字段名称
*/
private String logicColumn;
/**
* 明文字段名称
*/
private String plainColumn;
......@@ -45,14 +41,6 @@ public class ColumnRule {
this.encryptKey = encryptKey;
}
public String getLogicColumn() {
return logicColumn;
}
public void setLogicColumn(String logicColumn) {
this.logicColumn = logicColumn;
}
public String getPlainColumn() {
return plainColumn;
}
......@@ -82,7 +70,6 @@ public class ColumnRule {
return "ColumnRule{" +
"encryptType='" + encryptType + '\'' +
", encryptKey='" + encryptKey + '\'' +
", logicColumn='" + logicColumn + '\'' +
", plainColumn='" + plainColumn + '\'' +
", cipherColumn='" + cipherColumn + '\'' +
", 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