一、整体架构
上一篇文章说了shardingsphere是启动的,借助与netty框架
整体数据加解密的流程
1.处理流程
ShardingSphere 通过对用户输入的 SQL 进行解析,并依据用户提供的加密规则对 SQL 进行改写,从而实现对原文数据进行加密。 在用户查询数据时,它仅从数据库中取出密文数据,并对其解密,最终将解密后的原始数据返回给用户。 Apache ShardingSphere 自动化 & 透明化了数据加密过程,让用户无需关注数据加密的实现细节,像使用普通数据那样使用加密数据。
它更多的是提供列级加密,可以实现两种加密方式。
- 静态加密,在配置文件中定义,缺点:如果重新配置加密字段的话,需要重启proxy
rules:
- !ENCRYPT
encryptors:
# 加密器的名称,下面会使用
test_col1:
props:
# 加密模式两种常用的 ECB、CBC
sm4-mode: ECB
sm4-key: a5731fb991a6f45b8b5fe45d43fc3a81
sm4-padding: PKCS5Padding
# 加密算法标识
type: MySm4
queryWithCipherColumn: true
tables:
# 表名
test:
columns:
# 逻辑列(这个逻辑列和实际物理列名一致)
col1:
# 实际物理列名,
cipherColumn: col1
# 加密器名称,上面定义的
encryptorName: test_col1
# 用户想要使用 查询的列名,相当于一个逻辑的作用
logicColumn: col1
name: test
- 动态加密,需要连接上代理,就和navicat连接mysql一样,执行shardingsphere自己的语言 distsql
创建加密规则:
CREATE ENCRYPT RULE t_encrypt (
COLUMNS(
(NAME=user_id,CIPHER=user_cipher,ENCRYPT_ALGORITHM(TYPE(NAME='AES',PROPERTIES('aes-key-value'='123456abc')))),
(NAME=order_id,CIPHER =order_cipher,ENCRYPT_ALGORITHM(TYPE(NAME='AES',PROPERTIES('aes-key-value'='123456abc'))))
));
修改加密规则:
ALTER ENCRYPT RULE t_encrypt (
COLUMNS(
(NAME=user_id,CIPHER=user_cipher,ENCRYPT_ALGORITHM(TYPE(NAME='AES',PROPERTIES('aes-key-value'='123456abc'))))
));
查看规则:
SHOW ENCRYPT TABLE RULE 表名;
2.加密规则
加密配置主要分为三部分:数据源配置,加密算法配置,加密表配置
数据源配置:指数据源配置。
加密算法配置:指使用什么加密算法进行加解密。目前 ShardingSphere 内置了三种加解密算法:AES,MD5 和 RC4。用户还可以通过实现 ShardingSphere 提供的接口,自行实现一套加解密算法。
加密表配置:用于告诉 ShardingSphere 数据表里哪个列用于存储密文数据(cipherColumn)、使用什么算法加解密(encryptorName)、哪个列用于存储辅助查询数据(assistedQueryColumn)、使用什么算法加解密(assistedQueryEncryptorName)以及用户想使用哪个列进行 SQL 编写(logicColumn)。
3.SQL的一生
如果此时使用navicat连接代理(也就是shardingproxy),并且发送一条sql,如: SELECT * FROM tttttt1_copy1
那么在代理中到底是如何接收并返回的呢?
- 首先由各自的数据库编解码引擎来进行处理,MySQLPacketCodecEngine首先进行解码,命令包如下
- 到达一个统一流转的地方,其中大致流程为:
SQL解析->SQL路由->SQL改写->执行引擎->结果归并
private boolean executeCommand(final ChannelHandlerContext context, final PacketPayload payload) throws SQLException {
CommandExecuteEngine commandExecuteEngine = databaseProtocolFrontendEngine.getCommandExecuteEngine();
CommandPacketType type = commandExecuteEngine.getCommandPacketType(payload);
// 对byteBuf 进行读取,获取sql语句, 会对之前解析的请求报文段 分段解析
CommandPacket commandPacket = commandExecuteEngine.getCommandPacket(payload, type, connectionSession);
// 获取执行器 ,SQL解析流程最终会将SQL语句解析为 SQLStatement 对象
CommandExecutor commandExecutor = commandExecuteEngine.getCommandExecutor(type, commandPacket, connectionSession);
try {
// 遍历执行器,执行execute方法 ,会执行sql,返回sql语句执行结果
Collection<DatabasePacket<?>> responsePackets = commandExecutor.execute();
if (responsePackets.isEmpty()) {
return false;
}
responsePackets.forEach(context::write);
if (commandExecutor instanceof QueryCommandExecutor) {
commandExecuteEngine.writeQueryData(context, connectionSession.getBackendConnection(), (QueryCommandExecutor) commandExecutor, responsePackets.size());
}
return true;
} catch (final SQLException | ShardingSphereSQLException | SQLDialectException ex) {
databaseProtocolFrontendEngine.handleException(connectionSession, ex);
throw ex;
} finally {
commandExecutor.close();
}
}
- MySQLPacketCodecEngine然后进行编码,返回给客户端
二、总结
本篇主要介绍了,shardingsphere数据加密的流程、加密模式、sql经过代理到底干了些什么,下一偏将详细介绍一下