这个端到端加密的工具奶爸已经做出来好多个月了:cloudssh ,因为最开始没有设计好 cmd
命令的模板导致现在奶爸没有优化下去的兴致了,总结一下端到端加密中的设计模式,有意思的细节,就打住了。
端到端加密详解
名词解释
MasterKey:明文密码以服务器返回的加密途径加密后的 key,此 key 用来加密个人账户下的所有数据使用
EncKey:MasterKey 的再 hash,hash 方法固定,循环次数较小,只是 hash 后提供给服务器当作密码鉴权使用
对称密钥:公钥用来加密 Team 的私钥,私钥由 MasterKey 加密后储存在服务器中,需要时解密来用
Team 密钥:公钥储存在 Team 表,私钥储存在每个成员那里
用户注册
sequenceDiagram
participant 用户
participant 客户端
participant 服务器
用户->>客户端: 注册账户
客户端->>服务器: 询问加密masterKey的加密方式
服务器->>客户端: 返回masterKey加密方式
用户->>客户端: 提供邮箱、明文密码
客户端->>服务器: 密码为依据明文密码生成 hash 后的 encKey 的 hash,生成对称加密密钥,将对称加密私钥由 encKey 加密后一起提交至后端
服务器-->>客户端: 注册成功
在注册流程中,明文密码不会离开你的电脑。服务器端保存的密码是用来加密数据的 encKey 的 hash 的 bcrypt hash 后的值,和 encKey 的 hash 方式。
用户登录
sequenceDiagram
participant 用户
participant 客户端
participant 服务器
用户->>客户端: 提供账户邮箱、密码登录
客户端->>服务器: 预询问该账户加密masterKey的加密方式
服务器-->>客户端: 返回masterKey加密方式
客户端->>服务器: 按照加密方式将明文密码加密为 masterKey,然后按照固定模式生成 encKey 进行 hash 提交到服务器鉴权
服务器-->客户端: 登录成功
个人数据
读取
sequenceDiagram
participant 用户
participant 客户端
participant 服务器
用户->>客户端: 读取 数据1
客户端->>服务器: 请求 数据1
服务器-->>客户端: 返回 数据1
客户端-->>用户: 使用 masterKey 解密然后展示给用户
写入
sequenceDiagram
participant 用户
participant 客户端
participant 服务器
用户->>客户端: 写入 数据2
客户端->>服务器: 将 数据2 中除ID外的字段由 masterKey 加密,然后上传至服务器
服务器-->>客户端: 直接存入数据库
服务器-->>客户端: 写入成功
Team 数据
读取
sequenceDiagram
participant 用户
participant 客户端
participant 服务器
用户->>客户端: 读取 数据1
客户端->>服务器: 请求 数据1
服务器-->>客户端: 返回 数据1
客户端-->>用户: 使用 masterKey 解密 Team 的私钥,在用私钥解密数据,然后展示给用户
写入
sequenceDiagram
participant 用户
participant 客户端
participant 服务器
用户->>客户端: 写入 数据2
客户端->>服务器: 将 数据2 中除ID外的字段由 Team 公钥加密,然后上传至服务器
服务器-->>客户端: 直接存入数据库
服务器-->>客户端: 写入成功
概览
Team 成员管理
graph TD;
单人-->个人帐户;
个人帐户-->明文密码及ciperString;
明文密码及ciperString-->数据;
多人-->Team账户;
Team账户-->对称加密密钥;
对称加密密钥-->数据;
因为 Team 账户为多人服务,既要保证每个人都能读取、修改 Team 中的数据,又能使个人的数据维持私密安全。同样在添加与删除成员时,只需要操作 添加/删除 的管理员修改 Team 的公钥与私钥,而后便利相关成员,使用成员的公钥将新的 Team 私钥保存在成员处,成员即可使用更新的私钥读取数据,而被提出剔出的成员也无法再解密 Team 数据。
目前的缺陷
客户端为方便用户明文储存了用户的明文密码在 ~/.cloudssh.json
中,这是极不安全的。请看这篇博文 「Stop saving credential tokens in text files 」端到端加解密,包括处理多人加解密的流程比较复杂,奶爸的描述能力有限,欢迎与博主进行交流。