跳到主要内容

.blink 打点文件格式

BlinkLife 使用自定义 .blink 二进制格式存储和分享打点数据,内容为 AES-256-CBC 加密的 JSON,v2 版本增加 HMAC-SHA256 完整性校验。

格式定义

v2 格式(当前版本,写入时使用)

偏移长度 (字节)内容说明
04BLNK魔数 (0x42 0x4C 0x4E 0x4B)
410x02版本号
516IVAES-CBC 初始化向量(随机生成)
2132HMACSHA-256 HMAC(对密文计算)
53可变密文AES-256-CBC 加密的 JSON

v1 格式(已废弃,仅兼容读取)

偏移长度 (字节)内容说明
04BLNK魔数
410x01版本号
516IVAES-CBC 初始化向量
21可变密文AES-256-CBC 加密的 JSON

明文格式(兼容旧 .txt/.json)

BLNK 魔数头,直接是 UTF-8 编码的 JSON 文本。

加密算法

参数
算法AES-256-CBC
密钥长度32 字节
IV16 字节随机生成
PaddingPKCS7
完整性HMAC-SHA256 (v2 only)
方案Encrypt-then-MAC

Encrypt-then-MAC 流程

写入:
plaintext → AES-CBC 加密 → ciphertext
ciphertext → HMAC-SHA256 → hmac
输出: BLNK + 0x02 + IV + hmac + ciphertext

读取:
输入 → 解析 header → 提取 hmac 和 ciphertext
ciphertext → HMAC-SHA256 → computed_hmac
常量时间比较(hmac, computed_hmac) → 通过则解密
ciphertext → AES-CBC 解密 → plaintext

自动格式检测

读取文件字节

├── 前 4 字节 == "BLNK"?
│ ├── 第 5 字节 == 0x02 → v2 解密(HMAC 校验 + AES)
│ ├── 第 5 字节 == 0x01 → v1 解密(仅 AES)
│ └── 其他 → BlinkFileException(unsupportedVersion)

└── 前 4 字节 != "BLNK"
└── 作为 UTF-8 明文返回

异常类型

错误类型触发条件用户提示
emptyFile文件 0 字节打点文件为空
invalidFormat文件太短或头部无效文件格式无效
unsupportedVersion版本号不支持不支持的文件版本
integrityFailedHMAC 校验不通过文件已损坏或被篡改
decryptionFailedAES 解密异常解密失败

版本演进

版本日期变更向后兼容
明文初始.txt/.json 纯文本读取兼容
v12026-04-04AES-256-CBC 加密读取兼容
v22026-04-04+HMAC-SHA256 完整性校验读取兼容 v1 和明文

读写方一览

写入方

位置方法场景
FileServicesaveRecordingData()录制结束保存
review_detail_pageBlinkCrypto.writeFile()打点编辑/删除
dot_align_pageBlinkCrypto.writeFile()对齐偏移写入

读取方

位置方法场景
FileServiceloadRecordingData()回放页加载
markers_import_serviceBlinkCrypto.readFile()导入打点文件
external_clip_pageBlinkCrypto.readFile()外部导入
recording_sync_serviceBlinkCrypto.readFileSync()云同步

安全考量

  1. 密钥管理:密钥硬编码在 blink_crypto.dart,主要防止非 BlinkLife 应用读取,不是高安全级别加密
  2. 常量时间比较:HMAC 校验使用 _constantTimeEquals() 防计时攻击
  3. 随机 IV:每次写入生成新的 16 字节随机 IV

风险点

风险影响缓解
密钥泄露所有 .blink 文件可被解密密钥不在日志/错误信息中出现
v1 无完整性校验被篡改后无法检测v1 仅兼容读取,新写入一律 v2
空文件/截断文件解密崩溃BlinkFileException 捕获 + 字节长度校验

相关文档