[Hex]SQLCipher3文件结构解析

[toc]最近在研究SQLCipher3文件结构,官网上寥寥几句话就把人打发了,琢磨了好半天,看了不少人的图和代码终于搞明白了,感谢开源!所以我也遵循下GPL2.0协议,把内容公布给大家

SQLCipher官网原文

原文在这里,下面捡重要的讲

  • The encryption algorithm is 256-bit AES in CBC mode
  • Each database page is encrypted and decrypted individually. The default page size is 4096 bytes but this can be adjusted at runtime.
  • Each page has it’s own random initialization vector. The IV is generated by a cryptographically secure random number generator and is stored at the end of the page. IVs are regenerated on write so that the same IV is not reused on subsequent writes of the same page data.
  • Every page write includes a Message Authetication Code (HMAC-SHA512) of the ciphertext and the initialization vector at the end of the page. The MAC is checked when the page is read back from disk. If the ciphertext or IV have been tampered with or corrupted the HMAC check will cause SQLCipher to report a problem with the database.
  • When initialized with a passphrase SQLCipher derives the key data using PBKDF2-HMAC-SHA512. Each database is initialized with a unique random salt in the first 16 bytes of the file. This salt is used for key derivation and it ensures that even if two databases are created using the same password, they will not have the same encryption key. The default configuration uses 256,000 iterations for key derivation.
  • The key used to calculate page HMACs is different that the encryption key. It is derived from the encryption key and using PBKDF2 with 2 iterations and a variation of the random database salt.

大概意思总结为

  • 加密方式是AES256CBC
  • 按页加密,默认页4096字节,但是可以改
  • 每页有个IV在页最后,每次修改IV都会变
  • 每页包含校验码,算法是HMAC-SHA512,校验码会校验IV是否被篡改
  • Key的生成算法是PBKDF2-HMAC-SHA512,每个数据库文件初始化的时候在文件最头16字节放了算法需要的盐,计算轮次默认256000次,不使用密码直接解密
  • HMAC计算用的Key通过Key产生,也用PBKDF2-HMAC-SHA512,计算轮次2次

是不是很迷啊

  • HMAC Key直接用Key计算出来永远是算不对的
  • 页结构也不是很清晰

解析

页结构

页结构主要分3部分

[页头][页内容][页保留字段]
  • 页头:可以是0个或1个
  • 页内容:主要存放数据
  • 页保留字段:用于存放参数

每一页都是固定长度,也就是页大小

页头

在SQLCipher里只有第一页有页头存放的是Salt,也就是说

第一页的内容是

[DB_SALT][页内容][页保留字段]

页保留字段

页保留字段是用来存放参数的,根据官方文档可知,页保留字段用于存放HMAC,AES256CBC的参数

所以页保留必须存放的内容有

  • [IV]

  • [HMAC]

那么问题来了,顺序和长度呢?不知道顺序只能测试了,还好有大神的代码,看了看,发现顺序为

[IV][HMAC]

对于AES256CBC加密方式,IV的大小是16字节

对于HMAC-SHA512,HMAC是20字节

看看,有坑吧?

这还没完,通过阅读代码发现

页保留字段单元和页内容单元要统一,必须要是加密Block的整数倍,不足的要不足

好了,那么结构就是

[IV][HMAC][Padding]

要是不是dalao指导,还真的是一脸懵逼,我当时不知道有Padding,怎么测都测不出来,人间不拆。希望官方什么时候仔细写好文档吧。

通过官方只言片语得知HMAC检验页内容和IV

那么HMAC检验内容则有

  • 页内容
  • IV

问题又来了,顺序呢?又参考了dalao的代码

顺序是

[页内容][IV]

等等这还没完,为什么后面还有个玩意?为什么官网文档木有写?(;´༎ຶД༎ຶ`) 哭死,研读了半个月,终于明白了,是大端UInt8类型的页码,我心中奔腾过一群羊驼。。。

[页内容][IV][Uint8页码]

Ummmm?Uint8也就是说最多只有2^8页?这个有待测试啊,不知道页多了是不是会变成Uint16,Uint32,还是说一下呢?神坑啊!!有木有

好了,为什么还会解不出来数据呢?

到底哪里还有坑啊!摔~

IV知道了,Key知道了,那么出问题的只能是密文了

肯定是把其他东西也加到密文里了,再次膜拜dalao得知

页头不是页内容!页头不是页内容!重要的话说两次!

AES256CBC的加密内容是有效数据区

哎呦我去,终于解开了

Key

知道了Key的生成算法是PBKDF2-HMAC-SHA512,用IV一解数据区

HMAC计算用的Key通过Key产生,也用PBKDF2-HMAC-SHA512,计算轮次2次

密文我都解开了,那么为什么校验不通过呢?PBKDF2,Key是官方说的不会错,轮次也说了,不会错,那么出问题的只有SALT

再次膜拜dalao代码,还有各种博客

尼玛HMAC的SALT是页头那个SALT按字节异或0x3a,坑爹呢这是!

为什么官网没写?为什么官网没写?为什么官网没写!!!!

我要拿出来50m的大砍刀了

不过至此,所有的要点都知道了。可以直接把SQLCipher的文件变成SQLite3的,再参考SQLite的格式放在合适位置就是,怎么合适呢?百度上一大片,我就不罗嗦了

发表评论

电子邮件地址不会被公开。 必填项已用*标注