前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[MYSQL] 恢复加密的mysql表

[MYSQL] 恢复加密的mysql表

原创
作者头像
大大刺猬
发布2024-11-12 14:41:39
710
发布2024-11-12 14:41:39
举报
文章被收录于专栏:大大刺猬

导读

通常我们不会在mysql层面上使用加密插件, 虽然加密之后会比较安全, 但加密太耗时了, 而且key一旦丢了, 就GG了. 而且数据库服务器通常不会对外提供服务, 即使对外提供服务,也有权限验证的. 总的来说,数据库层加密有丢丢鸡肋.

但架不住有客户使用啊.... 由于使用者少, 遇到问题了就不好处理, 这里来记录一下加密表的常见错误及其处理过程.

案例

我们知道mysql可以通过迁移表空间的方式来快速迁移数据, 非常的方便. 那么对于加密的表的迁移还会这么顺利么?

数据构造

本次是在8.0.28环境模拟的, 可使用如下sql来构造数据, 对于

代码语言:sql
复制
create table t20241112(id int primary key, name varchar(200)) ENCRYPTION='y';
insert into t20241112 values(1,'ddcw');
insert into t20241112 values(2,'https://github.com/ddcw/ibd2sql');

数据迁移

由于表空间迁移涉及到keyring file的问题, 我们就使用本地导出导入来模拟吧

场景1: 可行的特殊情况

代码语言:sql
复制
-- 获取表结构
show create table t20241112;
-- 源端表空间导出
flush table t20241112 for export;
-- 拷贝到其它目录(ibd,cfg,cfp)
cp -ra /data/mysql_3314/mysqldata/db1/t20241112.* /tmp
-- 删除表
unlock tables;
drop table t20241112;
-- 创建表并导入数据
create table t20241112(id int primary key, name varchar(200)) ENCRYPTION='y';
alter table t20241112 discard tablespace;
cp -ra /tmp/t20241112.* /data/mysql_3314/mysqldata/db1
alter table t20241112 import tablespace;

这种其实通常是没得问题的

场景2: 无.cfp文件

但有时候有的小伙伴会忘记拷贝.cfp文件了, 就会遇到如下报错

代码语言:txt
复制
ERROR 1808 (HY000): Schema mismatch (Table is in an encrypted tablespace, but the encryption meta-data file cannot be found while importing.)

报错说是没找到: 加密的元数据文件, 就是那个.cfp文件. 欸, 那我们再创建一个一样的表,做flush,并保留下cfg和cfp是否就可以了呢?, try it

场景3: 重新生成cfp文件

重新生成cfp,并重新导入后报错如下

代码语言:txt
复制
ERROR 1815 (HY000): Internal error: Cannot reset LSNs in table `db1`.`t20241112` : Data structure corruption

很遗憾, 并不行. 报错是数据结构有问题. 而我们的数据文件应该是没得问题的. 那问题在哪呢?

分析

由于前面我们解析过keyring file文件, 知道了实际的key是放在表空间文件里面的, 而keyring file里面只是key的key, 而且可能轮转(我们这里没做过轮转,就不考虑轮转的场景了). 那我们对比下前后的cfp文件的差异吧,

发现确实有差异. 也就是每次做alter table tablename for export生成的cfp文件内容是不一致的, 即要求cfp和ibd文件对应起来才能解析. 但我们现在的场景是不小心丢了cfp文件, 那么就永远无法恢复数据了么. keyring file都还在的啊! 欸嘿, 我们前面有一章讲过加密的ibd文件怎么解析(赶兴趣的自己去翻). 也就是我们还可以直接解析这个加密的ibd文件来恢复数据.

解决

首先是下载ibd2sql,

代码语言:shell
复制
wget https://github.com/ddcw/ibd2sql/archive/refs/heads/main.zip
unzip main.zip
cd ibd2sql-main

然后是提取出DDL和数据. (虽然DDL可以找业务测要, 但我们还是自己动手,丰衣足食)

代码语言:shell
复制
python3 main.py /tmp/t20241112.ibd

看来是识别到这个ibd文件是加密的了, 要求我们提供keyring file.

代码语言:shell
复制
python3 main.py /tmp/t20241112.ibd --keyring-file /usr/local/mysql/keyring/keyring

如果指定了错误的keyring文件的话, 也是会提示的. 所以keyring文件千万别整丢了!!!

代码语言:shell
复制
python3 main.py /tmp/t20241112.ibd --keyring-file /usr/local/mysql/keyring/keyring2

看来是解析正确了. 那来瞅瞅数据呢

代码语言:shell
复制
python3 main.py /tmp/t20241112.ibd --keyring-file /usr/local/mysql/keyring/keyring2 --sql

吼吼, 数据也是没得问题的.

总结

  1. 之前应该忘记讲了, mysql在使用AES-CBC解析的时候, 对于余下的10字节,并不是使用的CBC模式的那几种填充方式, 而是使用的innodb的. Advanced Encryption Standard (AES) is the only supported encryption algorithm. InnoDB tablespace encryption uses Electronic Codebook (ECB) block encryption mode for tablespace key encryption and Cipher Block Chaining (CBC) block encryption mode for data encryption. Padding is not used with CBC block encryption mode. Instead, InnoDB ensures that the text to be encrypted is a multiple of the block size.

即最后10字节会加上前面正常加密的22字节(cbc要求iv,所以要2个block(2*16),即一共32字节) (38--16374:aes:cbc + -32:aes:cbc:-10)

对于原理性的东西,兴趣不大, 就简单画个示意图吧:

我们只解析index page, 对于index page而言,最后10字节用处不大.(page_dir0:2 + checksum:4 + lsn:4)

  1. 还是那句话, 尽量不要使用数据库加密.

吐槽下甲方的工时饱和度要求, 算了,牛马不配...

参考:

https://dev.mysql.com/doc/refman/8.0/en/innodb-data-encryption.html

https://github.com/ddcw/ibd2sql

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导读
  • 案例
    • 数据构造
      • 数据迁移
        • 场景1: 可行的特殊情况
        • 场景2: 无.cfp文件
        • 场景3: 重新生成cfp文件
    • 分析
    • 解决
    • 总结
    相关产品与服务
    云数据库 MySQL
    腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档