我应该使用哪种公钥算法来加密一小部分字节?

时间:2019-08-07 16:28:01

标签: algorithm encryption cryptography public-key-encryption

背景故事: 我正在尝试编写自己的日志记录库。这是出于爱好目的。对我来说,有一个必须要做的事情:记录的数据必须不对称加密。日志消息始终直接写入文件中,不进行缓存,不等待任何队列。

这意味着我将必须加密一小堆消息。即使瓶颈可能是缺少缓存和IO操作,我还是要明智地选择加密算法。

摘要:

  • 我必须加密大量小数据(<200字节)
  • 算法必须是非对称的,我想用公钥加密,并且唯一能够用我自己的私钥解密

您建议使用哪种算法?

1 个答案:

答案 0 :(得分:1)

您似乎在解释“日志数据必须非对称加密”,这实际上是一种低级别的要求。 “记录的数据必须非对称加密”不是安全要求,而是一种实现方法。这是一种糟糕的实现方法,因为它要求您设计自己的加密协议(可以使用标准原语,但只能以非标准方式使用),并且会产生令人讨厌的局限性。

一个更合理的要求是“生成日志的机器一定不能解密它们”。这是一项安全要求:这是关于资产(日志)的安全性(特别是其机密性)的要求。

实现此安全要求的方法确实是使用非对称加密。但是,您不必采用非对称加密原语并将日志作为输入传递给它。相反,您使用hybrid encryption:生成一个对称密钥,使用该密钥加密日志,使用该非对称密钥加密该对称密钥,然后删除该对称密钥。

执行此操作的最佳方法是使用性能良好的库。 crypto_boxcrypto_box_easycrypto_box_sealNaCllibsodium函数是此处的黄金标准。您传递用于加密的公共密钥,要签名的消息,然后得到一个加密的“盒子”,该盒子只能用私钥解密。 crypto_box_easycrypto_box还将自己的私钥作为参数来签署日志,这在玩具示例中可能并不需要,但是在现实世界中通常很重要。 crypto_box_easycrypto_box也采用随机数作为参数;该值可以是任何可以公开但不能重复使用的值,例如crypto_box_NONCEBYTES字节的随机字符串。

例如,如果您不想使用crypto_box,因为您想学习如何在后台进行操作,则必须使用所选的低级密码库手动组装零件。根据您使用哪种非对称加密方式,流程有所不同。使用诸如ECIES之类的密钥建立方法:

  1. 生成随机的一次性私钥 y
  2. 计算相应的公共价值 g y
  3. 使用收件人的公钥 g x ,计算共享密钥 g xy
  4. 应用key derivation function之类的HKDF确定性地生成秘密对称密钥,例如AES密钥或Chacha20_Poly1305密钥。
  5. 使用对称密钥对日志消息进行加密,例如使用AES-GCM或Chacha20_Poly1305。
  6. (可选)对日志消息进行哈希处理,并使用您的公共密钥对其进行签名。
  7. 从内存中擦除一次性私钥,共享密钥,对称对称密钥,明文日志和任何其他中间值。
  8. 发送密文,公共值 g y 和可选的签名。

使用诸如RSA-OAEP之类的密钥加密方法:

  1. 生成随机的一次性秘密密钥,例如AES密钥或Chacha20_Poly1305密钥。
  2. 使用对称密钥对日志消息进行加密,例如使用AES-GCM或Chacha20_Poly1305。
  3. (可选)对日志消息进行哈希处理,并使用您的公共密钥对其进行签名。
  4. 使用收件人的公共密钥对对称密钥进行加密。
  5. 从内存中擦除一次性密钥,纯文本日志和任何其他中间值。
  6. 发送密文,公共值 g y 和可选的签名。

如果您确定可以使用相同的对称密钥对多个日志消息进行加密,则手动执行这些步骤可能会提高性能。这具有性能优势,因为非对称操作比对称操作慢。这样做没有长期的安全隐患。唯一的安全缺陷是短期缺陷:仍然可以解密当前对称密钥中的所有日志。例如,如果您确定破坏系统的攻击者可以读取最后一分钟的日志是可以的,那么您可以每分钟更新对称密钥。