it_worker365

   ::  ::  ::  ::  :: 管理

来看下 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);
}
View Code

顺着调用方,我们又找到了熟悉的代码

@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()));
            }
        }
    }
}

 

posted on 2021-07-09 17:10  it_worker365  阅读(69)  评论(0编辑  收藏  举报