Metadata-Version: 2.4
Name: otpfile
Version: 0.1.0
Summary: 使用一次性密码本存储重要文件.
Author-email: songwei <github@songwei.name>
License: MIT
Project-URL: homepage, https://github.com/xdusongwei/otpfile
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: test
Requires-Dist: coverage>=7.13.1; extra == "test"
Requires-Dist: pytest>=9.0.2; extra == "test"
Dynamic: license-file

# otpfile
使用一次性密码本存储重要文件.


对于一些重要文件或者密钥, 可以使用物理介质比如纸或者单独的存储器去保存, 这些需要维护的介质可能会遇到丢失或者损坏的风险. 

为了避免物理介质维护不当的风险, 存储在云存储中是个好办法, 不过存储在云存储中, 文件可能会被分析或者泄露,
所以为了安全使用云存储记录重要文件, 可以设计一套加密文件方案, 使得:

*   加密后的文件有多份
*   单独的文件只是解密的一部分参数
*   不需要为此维护密码


实现这个方案需要使用[One-time pad](https://en.wikipedia.org/wiki/One-time_pad), 构建多个与原文等长的密码本,
然后将密文结果和各个密码本分散存储, 使得任何单独的泄露事件对数据无影响.

例如一种方案是产生密文文件和1个密码本文件, 然后将这两个文件复制为四个.
分别保存在 GoogleDrive, OneDrive, Dropbox, 百度云, 使得每一家平台不会造成泄露风险并且进行冗余保存.


文件结构
------

``` text
File Description:

涉及到的签名和哈希均为SHA256

整体结构:
+--------+------------+-------------+--------+----+-------------+------------+----------------+
|OTP1(4B)|groupID(64B)|fileHash(32B)|size(4B)|name|fileCount(4B)|segCount(4B)|seg[1..segCount]|
+--------+------------+-------------+--------+----+-------------+------------+----------------+

首部的前四个字节标识类型与版本
groupID: 对于所有加密过的文件的统一标识 
fileHash: 原文件的签名信息, 用于还原时校验解密数据
name: 被加密文件的名称, 用于还原时创建文件
fileCount: 需要创建多少个文件, 至少为2(密文文件+1个密码本文件)
segCount: 文件包含的段数量, 每个段可以承载不超过128KB的密文或者密码本

对于每个段:
+---------------------------+--------+----+--------+-----+--------------+
|signatures(fileCount * 32B)|size(4B)|body|size(4B)|nonce|signature(32B)|
+---------------------------+--------+----+--------+-----+--------------+

signatures: 所有文件中这个位置的段, 其数据的签名汇总, 用于校验所有文件的这一批段数据是否缺失或者异常
signature: 该段的在此文件的签名, hash(groupID + body + nonce)
```


用法
---

```python
from otpfile import OTP


o = OTP()
files: list[str] = o.encrypt_file('/path/to/secret.data', '/path/to/write/output/folder')
o.decrypt_file(files, '/path/to/write/recover/folder')
```
