我应该使用哪种 public 密钥算法来加密小块字节?
Which public key algorithm should I use for encrypting small chunk of bytes?
背景故事:
我正在尝试编写自己的日志记录库。这是出于爱好目的。有一个对我来说是必须的:记录的数据必须非对称加密。日志消息始终直接写入文件,不发生缓存,不等待任何队列。
这意味着我将不得不加密一堆小块消息。尽管瓶颈可能是缺少缓存和 IO 操作,但我还是希望明智地选择加密算法。
总结:
- 我必须加密大量小数据(<200 字节)
- 算法必须是非对称的,我想用 public 密钥加密并且只能用我自己的私钥解密它
你建议什么算法?
您似乎将“记录的数据必须非对称加密”从字面上解释为低级要求。 “记录的数据必须非对称加密”不是安全要求,而是一种实现方法。这是一个糟糕的实现方法,因为它需要您设计自己的加密协议(您可以使用标准原语,但只能以非标准方式使用),并且它会有恼人的限制。
更合理的要求是“产生日志的机器不能解密”。这是一个安全要求:它是对资产(日志)的安全要求(特别是它们的机密性)。
实现这个安全需求的方法确实是使用非对称加密。但是您不会采用非对称加密原语并将日志作为输入传递给它。相反,您使用 hybrid encryption:生成对称密钥,用它加密日志,用非对称密钥加密对称密钥,然后擦除对称密钥。
最好的方法是使用一个能很好地完成它的库。 crypto_box
, crypto_box_easy
and crypto_box_seal
functions of NaCl or libsodium 是这里的黄金标准。您传递用于加密的 public 密钥和要签名的消息,然后您将得到一个加密的“盒子”,它只能用私钥解密。 crypto_box_easy
和 crypto_box
也将您自己的私钥作为参数来签署日志,这在您的玩具示例中可能不想要,但在现实世界中通常很重要。 crypto_box_easy
和 crypto_box
也以随机数作为参数;这可以是 public 但不能使用两次的任何值,例如 crypto_box_NONCEBYTES
字节的随机字符串。
如果你不想使用 crypto_box,例如因为你想了解它是如何在引擎盖下完成的,你必须手动 assemble 这些部分,使用你选择的低-级密码库。流程因您使用的非对称加密类型而异。用ECIES这样的密钥建立方法:
- 生成随机的一次性私钥y.
- 计算对应的public值gy.
- 使用接收者的public密钥gx,计算共享密钥gxy.
- 应用 key derivation function such as HKDF 确定性地生成秘密对称密钥,例如 AES 密钥或 Chacha20_Poly1305 密钥。
- 使用秘密对称密钥加密日志消息,例如使用 AES-GCM 或 Chacha20_Poly1305。
- 可选地,散列日志消息并使用您的 public 密钥对其进行签名。
- 从内存中擦除一次性私钥、共享密钥、秘密对称密钥、明文日志和任何其他中间值。
- 发送密文、public值gy和可选的签名。
使用 RSA-OAEP 等密钥加密方法:
- 生成随机的一次性密钥,例如 AES 密钥或 Chacha20_Poly1305 密钥。
- 使用秘密对称密钥加密日志消息,例如使用 AES-GCM 或 Chacha20_Poly1305。
- 可选地,散列日志消息并使用您的 public 密钥对其进行签名。
- 使用收件人的 public 密钥加密对称密钥。
- 从内存中擦除一次性密钥、明文日志和任何其他中间值。
- 发送密文、public值gy和可选的签名。
如果您认为可以使用相同的对称密钥加密多条日志消息,则手动执行这些步骤可能会提高性能。这具有性能优势,因为非对称操作比对称操作慢。这样做没有长期的安全缺陷。唯一的安全缺陷是短期的:来自当前对称密钥的所有日志仍然可以被解密。例如,如果您决定如果破坏您系统的攻击者可以读取最后一分钟的日志是可以的,那么您可以每分钟更新一次对称密钥。
背景故事: 我正在尝试编写自己的日志记录库。这是出于爱好目的。有一个对我来说是必须的:记录的数据必须非对称加密。日志消息始终直接写入文件,不发生缓存,不等待任何队列。
这意味着我将不得不加密一堆小块消息。尽管瓶颈可能是缺少缓存和 IO 操作,但我还是希望明智地选择加密算法。
总结:
- 我必须加密大量小数据(<200 字节)
- 算法必须是非对称的,我想用 public 密钥加密并且只能用我自己的私钥解密它
你建议什么算法?
您似乎将“记录的数据必须非对称加密”从字面上解释为低级要求。 “记录的数据必须非对称加密”不是安全要求,而是一种实现方法。这是一个糟糕的实现方法,因为它需要您设计自己的加密协议(您可以使用标准原语,但只能以非标准方式使用),并且它会有恼人的限制。
更合理的要求是“产生日志的机器不能解密”。这是一个安全要求:它是对资产(日志)的安全要求(特别是它们的机密性)。
实现这个安全需求的方法确实是使用非对称加密。但是您不会采用非对称加密原语并将日志作为输入传递给它。相反,您使用 hybrid encryption:生成对称密钥,用它加密日志,用非对称密钥加密对称密钥,然后擦除对称密钥。
最好的方法是使用一个能很好地完成它的库。 crypto_box
, crypto_box_easy
and crypto_box_seal
functions of NaCl or libsodium 是这里的黄金标准。您传递用于加密的 public 密钥和要签名的消息,然后您将得到一个加密的“盒子”,它只能用私钥解密。 crypto_box_easy
和 crypto_box
也将您自己的私钥作为参数来签署日志,这在您的玩具示例中可能不想要,但在现实世界中通常很重要。 crypto_box_easy
和 crypto_box
也以随机数作为参数;这可以是 public 但不能使用两次的任何值,例如 crypto_box_NONCEBYTES
字节的随机字符串。
如果你不想使用 crypto_box,例如因为你想了解它是如何在引擎盖下完成的,你必须手动 assemble 这些部分,使用你选择的低-级密码库。流程因您使用的非对称加密类型而异。用ECIES这样的密钥建立方法:
- 生成随机的一次性私钥y.
- 计算对应的public值gy.
- 使用接收者的public密钥gx,计算共享密钥gxy.
- 应用 key derivation function such as HKDF 确定性地生成秘密对称密钥,例如 AES 密钥或 Chacha20_Poly1305 密钥。
- 使用秘密对称密钥加密日志消息,例如使用 AES-GCM 或 Chacha20_Poly1305。
- 可选地,散列日志消息并使用您的 public 密钥对其进行签名。
- 从内存中擦除一次性私钥、共享密钥、秘密对称密钥、明文日志和任何其他中间值。
- 发送密文、public值gy和可选的签名。
使用 RSA-OAEP 等密钥加密方法:
- 生成随机的一次性密钥,例如 AES 密钥或 Chacha20_Poly1305 密钥。
- 使用秘密对称密钥加密日志消息,例如使用 AES-GCM 或 Chacha20_Poly1305。
- 可选地,散列日志消息并使用您的 public 密钥对其进行签名。
- 使用收件人的 public 密钥加密对称密钥。
- 从内存中擦除一次性密钥、明文日志和任何其他中间值。
- 发送密文、public值gy和可选的签名。
如果您认为可以使用相同的对称密钥加密多条日志消息,则手动执行这些步骤可能会提高性能。这具有性能优势,因为非对称操作比对称操作慢。这样做没有长期的安全缺陷。唯一的安全缺陷是短期的:来自当前对称密钥的所有日志仍然可以被解密。例如,如果您决定如果破坏您系统的攻击者可以读取最后一分钟的日志是可以的,那么您可以每分钟更新一次对称密钥。