在ECDH之后生成AES密钥

时间:2014-04-19 08:51:03

标签: android encryption aes

我正在使用ECDH在Alice和Bob之间拥有共享秘密,其中一个在Android上运行,另一个在嵌入式上运行。我的理解是,最佳实践是双方都生成AES密钥来加密消息。有人可以发一些关于Alice和Bob双方在使用ECDH就共享秘密达成一致后生成相同AES密钥的例子吗?

2 个答案:

答案 0 :(得分:4)

最好遵循NIST关于密钥协议方案的建议,例如:使用NIST SP 800-56A recommendations in the implementers guideNIST SP 800-108中指定的一种密钥派生方法。它描述了如何将秘密转换为字节,然后可以使用其中一个KDF转换为(多个)密钥。

请注意,密钥派生在1.50之后的Bouncy Castle的轻量级API中,因此也应该出现在Spongy Castle中。最常见的NIST算法位于org.bouncycastle.crypto.generators.KDFCounterBytesGenerator。你可以简单地在构造函数中给它任何HMAC(比如说HMAC SHA1),在初始化期间给它org.bouncycastle.crypto.params.KDFCounterParameters

请注意,与Perseids的答案相比,这更符合更好的加密实践,但可能更难理解/实施。

答案 1 :(得分:2)

ECDH成功运行后,你们两端都有相同的组元素。您现在需要将元素的统一编码定义为字节数组/八位字节流。使用散列函数(例如SHA256)可以将数组减少到256位值。如果需要派生几个键,可以在对每个键进行散列之前为每个键附加不同常量的字节数组。

一个简单的例子:让我们说你的椭圆曲线点是(51357992175,89175716892)。您可以将该曲线点表示为字符串"(51357992175,89175716892)"。对于不同的键,你可以附加一些字符串常量,如" MacKey"或"加密密钥"。要获得一些原始字节值,您可以使用utf8对这些字符串进行编码。总的来说,关键是:

macKey        = sha256("(51357992175,89175716892)MacKey".getBytes("UTF-8"))
encryptionKey = sha256("(51357992175,89175716892)EncryptionKey".getBytes("UTF-8"))

编辑,关于您的评论引起的问题("在我的情况下,我有一台服务器和许多客户每天都要接近他几次,并且需要使用不同的AES每次基于共享密钥的密钥。")关于如何生成大量密钥,每个密钥对应一次:

您正在进入加密协议设计的相当复杂的领域。请考虑以下问题:

  • 您如何保证为每个新的发送的消息生成不同的密钥?标准解决方案是使用计数器或随机数作为nonce(数字使用一次),每个都有自己的问题。 (计数器:即使在应用程序崩溃或备份恢复的情况下也必须严格单调。随机:它必须足够大以防止随机冲突 - 像256位就足够了 - 你必须不断地信任随机数发生器到好。)
  • 如何防止邮件重播攻击接收方?您可以跟踪所使用的每个nonce(存储密集型)或者可能使用单调计数器,以防nonce单调并拒绝任何nonce小于或等于单调计数器的消息。
  • 您如何对消息延迟重新排序选择性消息阻止作出反应?在许多情况下,重要的是能够注意到这些事件,然后您必须决定该做什么。 (例如,TL​​S需要双方之间的实时交互,并且如果任何事情无序到达,则中止连接,但是无法检测到延迟(除非现在臭名昭着的心跳用于ping连接)。)

通过我们后面的扩展警告,回到您的问题:对于每个新密钥,您可以使用密钥派生中包含的 nonce (使用一次的数字)为此目的生成一个唯一的密钥。我基本上正在重建类似于" 5.1 KDF的计数器模式"来自NIST SP 800-108,owlstead已经提到过,使用纯文本组件。在这一点上,我建议以任何方式阅读它,因为它不是那么长,并包含很多背景考虑因素。除了nonce之外,你应该尽可能地缩小密钥的使用范围。例如,在服务器端使用:

macKey = sha256(sha256("(51357992175,89175716892); MacKey; ServerToClient; 2755".getBytes("UTF-8")))

用于为从服务器到客户端的通信进行消息身份验证而生成的第2755个密钥。您可以看到以下组件:共享密钥(椭圆曲线点),密钥(mac)的目的,通信方向,计数随机数。此外,我在这里使用双哈希来防止哈希上的任何类型的length extension; HMAC在这里同样出色。在某些情况下,nonce本身可以并且必须与消息一起发布。它本身不包含任何敏感信息。