encrypt(), decrypt() 수정

master
mjkhan21 11 months ago
parent 5ed401050c
commit 61cf53c4bb

@ -4,7 +4,8 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.Executor;
@ -12,48 +13,67 @@ import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import cokr.xit.foundation.data.ARIA; import cokr.xit.foundation.data.ARIA;
@Intercepts({ @Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}), @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}),
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
}) })
public class EncryptionSupport extends MybatisPlugin { public class EncryptionSupport extends MybatisPlugin {
private boolean enabled; private boolean enabled;
private ARIA aria = new ARIA(); private ARIA aria;
private List<String> decrypted = Collections.emptyList();
private List<Adaptor> adaptors = Collections.emptyList(); private List<Adaptor> adaptors = Collections.emptyList();
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public void setEncryptor(ARIA encryptor) {
this.aria = encryptor;
}
public void setAdaptors(Adaptor... adaptors) {
this.adaptors = List.of(adaptors);
this.adaptors.forEach(adaptor -> adaptor.setARIA(aria));
}
@Override @Override
protected void configure() { protected void configure() {
String str = properties.getProperty("enabled", ""); String str = properties.getProperty("enabled", "");
enabled = !"false".equals(str); setEnabled(!"false".equals(str));
str = properties.getProperty("enc.key"); if (aria == null) {
aria.setKey(str); aria = new ARIA();
str = properties.getProperty("enc.algorithm"); aria.setKey(properties.getProperty("enc.key"));
if (!isEmpty(str)) str = properties.getProperty("enc.algorithm");
aria.setAlgorithm(str); if (!isEmpty(str))
aria.setAlgorithm(str);
str = properties.getProperty("dec.fields", ""); }
if (!isEmpty(str))
decrypted = List.of(str.split(","));
str = properties.getProperty("enc.adaptor", ""); str = properties.getProperty("enc.adaptor", "");
if (isEmpty(str)) return; if (isEmpty(str)) return;
adaptors = Stream.of(str.split(",")).map(name -> { List<Adaptor> adaptors = Stream.of(str.split(",")).map(name -> {
try { try {
Class<?> klass = Class.forName(name); Class<?> klass = Class.forName(name);
Adaptor adaptor = (Adaptor)klass.getConstructor().newInstance(); return (Adaptor)klass.getConstructor().newInstance();
adaptor.setARIA(aria);
return adaptor;
} catch (Exception e) { } catch (Exception e) {
throw runtimeException(e); throw runtimeException(e);
} }
}).toList(); }).toList();
setAdaptors(adaptors.toArray(new Adaptor[adaptors.size()]));
}
@Override
protected Object query(Executor executor, MappedStatement mappedStatement, Object obj, RowBounds rowBounds, ResultHandler<?> resultHandler) throws SQLException {
encrypt(obj);
return executor.query(mappedStatement, obj, rowBounds, resultHandler);
} }
@Override @Override
@ -71,18 +91,15 @@ public class EncryptionSupport extends MybatisPlugin {
} }
private void decrypt(Object obj) { private void decrypt(Object obj) {
if (!enabled || decrypted.isEmpty()) return; if (!enabled || adaptors.isEmpty()) return;
if (obj instanceof Map) adaptors.forEach(adaptor -> {
decrypt((Map<String, Object>)obj); if (!adaptor.supports(obj)) return;
}
protected void decrypt(Map<String, Object> map) {
decrypted.forEach(k -> {
if (!map.containsKey(k)) return;
Object v = map.get(k); adaptor
map.put(k, aria.decrypt((String)v)); .setTarget(obj)
.decrypt()
.clear();
}); });
} }
@ -104,10 +121,12 @@ public class EncryptionSupport extends MybatisPlugin {
} }
private void encrypt(Adaptor adaptor, Object obj) { private void encrypt(Adaptor adaptor, Object obj) {
if (!adaptor.setTarget(obj)) return; if (!adaptor.supports(obj)) return;
adaptor.encrypt(); adaptor
adaptor.clear(); .setTarget(obj)
.encrypt()
.clear();
} }
public abstract static class Adaptor { public abstract static class Adaptor {
@ -119,12 +138,32 @@ public class EncryptionSupport extends MybatisPlugin {
return this; return this;
} }
public boolean setTarget(Object obj) { public Adaptor setTarget(Object obj) {
this.obj = obj; this.obj = obj;
return true; return this;
}
public abstract boolean supports(Object obj);
public abstract boolean isEncrypted(String str);
public abstract Adaptor encrypt();
public abstract Adaptor decrypt();
protected void encrypt(Supplier<String> getter, Consumer<String> setter) {
String plain = getter.get();
if (isEmpty(plain) || isEncrypted(plain)) return;
setter.accept(aria.encrypt(plain));
} }
public abstract void encrypt(); protected void decrypt(Supplier<String> getter, Consumer<String> setter) {
String encrypted = getter.get();
if (isEmpty(encrypted) || !isEncrypted(encrypted)) return;
setter.accept(aria.decrypt(encrypted));
}
public void clear() { public void clear() {
obj = null; obj = null;

Loading…
Cancel
Save