来看下 Encrypt 功能
对用户输入的 SQL 进行解析,并依据用户提供的加密规则对 SQL 进行改写,从而实现对原文数据进行加密,并将原文数据(可选)及密文数据同时存储到底层数据库。 在用户查询数据时,它仅从数据库中取出密文数据,并对其解密,最终将解密后的原始数据返回给用户
核心基类,可以知道主要就是干加密解密操作的,具体自带的实现有两种AESEncryptAlgorithm/MD5EncryptAlgorithm,也可以自己添加以SPI方式载入
public interface EncryptAlgorithm extends ShardingSphereAlgorithm, ShardingSphereAlgorithmPostProcessor { /** * Encode. * * @param plaintext plaintext * @return ciphertext */ String encrypt(Object plaintext); /** * Decode. * * @param ciphertext ciphertext * @return plaintext */ Object decrypt(String ciphertext); }
顺着调用方,我们又找到了熟悉的代码
@Getter @Setter public abstract class EncryptParameterRewriter<T extends SQLStatementContext> implements ParameterRewriter<T>, EncryptRuleAware { private EncryptRule encryptRule; @Override public final boolean isNeedRewrite(final SQLStatementContext sqlStatementContext) { return isNeedRewriteForEncrypt(sqlStatementContext) && isNeedEncrypt(sqlStatementContext); } protected abstract boolean isNeedRewriteForEncrypt(SQLStatementContext sqlStatementContext); private boolean isNeedEncrypt(final SQLStatementContext sqlStatementContext) { for (String each : sqlStatementContext.getTablesContext().getTableNames()) { if (encryptRule.findEncryptTable(each).isPresent()) { return true; } } return false; } }
具体实现有
挑一个逻辑少的细看一下,逻辑比较清晰,就是加密解密信息重写,比较清晰
@Setter public final class EncryptPredicateParameterRewriter extends EncryptParameterRewriter<SQLStatementContext> implements SchemaMetaDataAware, QueryWithCipherColumnAware { private ShardingSphereSchema schema; private boolean queryWithCipherColumn; @Override protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatementContext) { return true; } @Override public void rewrite(final ParameterBuilder parameterBuilder, final SQLStatementContext sqlStatementContext, final List<Object> parameters) { List<EncryptCondition> encryptConditions = new EncryptConditionEngine(getEncryptRule(), schema).createEncryptConditions(sqlStatementContext); if (encryptConditions.isEmpty()) { return; } for (EncryptCondition each : encryptConditions) { if (queryWithCipherColumn) { encryptParameters(parameterBuilder, each.getPositionIndexMap(), getEncryptedValues(each, each.getValues(parameters))); } } } private List<Object> getEncryptedValues(final EncryptCondition encryptCondition, final List<Object> originalValues) { String tableName = encryptCondition.getTableName(); String columnName = encryptCondition.getColumnName(); return getEncryptRule().findAssistedQueryColumn(tableName, columnName).isPresent() ? getEncryptRule().getEncryptAssistedQueryValues(tableName, columnName, originalValues) : getEncryptRule().getEncryptValues(tableName, columnName, originalValues); } private void encryptParameters(final ParameterBuilder parameterBuilder, final Map<Integer, Integer> positionIndexes, final List<Object> encryptValues) { if (!positionIndexes.isEmpty()) { for (Entry<Integer, Integer> entry : positionIndexes.entrySet()) { ((StandardParameterBuilder) parameterBuilder).addReplacedParameters(entry.getValue(), encryptValues.get(entry.getKey())); } } } }