6 个稳定版本

1.0.12 2023 年 3 月 2 日
1.0.10 2023 年 2 月 28 日
1.0.4 2023 年 2 月 19 日

#1009密码学

MIT/Apache

465KB
435

包含 (ELF 可执行文件/库, 1MB) turnstile

旋转门 - 单向加密

旋转门加密数据,使得数据只能在另一台计算机上解密(不能在加密计算机上解密)。

从密码学角度来看,旋转门仅仅是围绕libsodium的box的一个包装。使用ECIES变体可以实现类似的功能。

加密

  • 源计算机生成一个临时密钥对。
  • 使用源计算机的私钥和目标计算机的公钥生成预计算密钥。
  • 使用预计算密钥加密消息。
  • 源计算机的临时公钥是加密消息的一部分,但不会保留。
  • 丢弃源计算机的临时私钥。

解密

  • 目标计算机有一个长期密钥对。
  • 使用目标计算机的私钥和源计算机的公钥(包含在加密消息中)生成预计算密钥。
  • 使用预计算密钥解密消息。

用例

日志记录

通过旋转门管道日志,使得日志只有在移动到具有目标私钥的计算机上才能读取。这意味着如果Web服务器等被入侵,历史日志也会受到保护。

加密文件

如果您被提供了收件人的公钥,您可以将数据加密并放在公共位置,知道只有他们才能解密它。(您甚至无法自己解密它,所以如果需要,您最好保留原始数据。)

您已经可以使用openssl或PGP做类似的事情,所以这并不太令人兴奋。

用法

在目标机器上创建base62 ed25519密钥

target:/some/dir $ turnstile keygen
new secret key written into /home/fadedbee/.turnstile/i8q8p2L8gZpZsPD8NRcTiFfQHLfrhoq3IvsaEwWzPJH.secret

在源机器上加密流

source:/other/dir $ echo "hello world" | turnstile encrypt i8q8p2L8gZpZsPD8NRcTiFfQHLfrhoq3IvsaEwWzPJH > filename.txt.t7e

在源机器上加密文件

source:/other/dir $ turnstile -i filename.txt -o filename.txt.t7e encrypt i8q8p2L8gZpZsPD8NRcTiFfQHLfrhoq3IvsaEwWzPJH

在目标机器上解密流

target:/some/dir $ cat filename.txt.t7e | turnstile decrypt
hello world

(filename.txt.t7e 包含目标计算机的公钥。解密会从 /home/fadedbee/.turnstile/i8q8p2L8gZpZsPD8NRcTiFfQHLfrhoq3IvsaEwWzPJH.secret 读取相关的私钥。)

在目标机器上解密文件

target:/some/dir $ turnstile -i filename.txt -o filename.txt.t7e -o decrypted.txt decrypt
target:/some/dir $ cat decrypted.txt
hello world

版本 1.0.X 的流/文件格式。

头部

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|FA|DE|DB|EE|t |u |r |n |s |t |i |l |e |Version |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                                               |
+            Encryptor's Public Key             +
|                                               |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                                               |
+        Intended Decryptor's Public Key        |
|             (informational only)              |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                 Initial Nonce                 |
+                       +--+--+--+--+--+--+--+--+
|                       |
+--+--+--+--+--+--+--+--+

数据块

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| Len |                                         |
+--+--+                                         +
|                                               |
+                  Ciphertext                   +
|                                               |
v                                               v

最后一个数据块

+--+--+
|00 00|
+--+--+

设计选择

权衡和妥协的文档。

要求私钥包含在文件中(在 ~/.turnstile 中)

本可以通过命令行指定目标密钥,而不是使用 ~/.turnstile

对于多用户机器来说,这可能会不安全,因为pstop会显示其他用户的命令行参数。

使用Base62

  • Base64更常见,但需要在shell命令中进行引号处理,并且不易于复制粘贴。
  • Base58有哨兵,可能对手动输入密钥有帮助,但长度更长且大小可变。
  • 巧合的是,43个62进制的数字提供了256.03位。log2(62)*43 == 256.03

将目标公钥包含在加密输出中

目标公钥在加密输出中存在没有加密学的需要,但我们仍然包含它。

优点

  • 允许解密只尝试一个密钥,而不是所有已知的密钥。
  • 用户可以检查.t7e文件以找到他们需要用于解密的公钥。

缺点

  • 向加密输出中添加可识别的信息。

使用~/.turnstile而不是~/.ssh中的Ed25519 SSH密钥

turnstile使用的加密与SSH的.ssh/id_ed25519.pub文件兼容。

使用现有的密钥会更好,但是

  • 我们需要向用户解释SSH密钥类型之间的区别。
  • 需要使用Base64和引号。

在块中使用16位的密文长度

为了处理流数据,我们必须将输入拆分成块,每个块可以依次解密。(解密包括完整性检查。)

较小的块有更多的开销,但允许较大的块则意味着每个小块有更多的长度开销。

我们可以使用可变大小的整数来表示长度,这可以节省一些空间,但会以一些CPU周期和复杂性为代价。

目前,我们已确定最大块大小为65,535字节。

对于大文件,每65,519字节的明文会产生一个包含2字节长度和65,535字节密文的块。

这不到0.03%的开销。鉴于使用u16表示块长度简单易行,这对于v1.0.0版本是可以接受的。

随机数生成

随机数不得为任何给定的公钥和私钥对重复使用。

每个块都使用不同的随机数进行加密,这个随机数只是初始随机数与块号的异或。

由于每条消息都是使用不同的密钥加密的,因此没有必要让初始随机数不同。但我们随机生成初始随机数并将其写入标题,以防万一...

依赖项

~21MB
~143K SLoC