我最近介绍了嵌入式系统中C的AES实现,并一直在寻找在无线点对多点链接(或初学者的点对点)中使用它的方法。
代码在我的平台上正确编译,当使用CTR模式提供的测试代码时,似乎可以正确给出结果(背对背(此CRT模式是我所需要的,因为我的数据包每个120字节,并且不能更改)。
本质上,发送器Tx应该使用tiny-AES加密功能来生成一个连续的加密数据包流,每个数据包120个字节,并在附加了CTR和报头的情况下进行发送,并在另一端通过以下方式接收和解密:接收器Rx。
可以设想,发送器Tx和接收器Rx使用完全相同的,只有我自己知道的密钥的微小AES代码。可以设置此密钥,并且在不同的Tx-Rx对上该密钥将有所不同。
我的问题特别涉及CRT模式,以及在Tx和Rx上同时使用以下功能:
/* Initialize context calling (iv can be NULL): */
void AES_ctx_init(AES_ctx *ctx, uint32_t keylen, const uint8_t *key, const uint8_t *iv);
/* ... or reset IV or key at some point: */
void AES_ctx_set_key(AES_ctx *ctx, uint32_t keylen, const uint8_t *key);
void AES_ctx_set_iv(AES_ctx *ctx, const uint8_t *iv);
所以
AES_ctx_init()
的用途是什么,在安全链接的加密/解密会话开始时仅执行一次吗?AES_ctx_set_iv()
函数的作用是什么?再次,在安全链接会话开始时仅执行一次吗?注释“ ...或在某个时候重置IV或密钥”对我来说还不清楚,这是我提出问题的原因...那就是在CRT模式下使用AES时何时需要重置IV?在无线链路中,由于存在噪声,并且如果未实施FEC,则由于不良的CRC,将迫使接收器丢弃数据包。在我的链接中,对接收到的120个字节的数据包进行CRC校验(按接收到的字节一一校验),如果CRC正确,则启动解密以恢复原始数据,但如果不正确,则丢弃数据。无论加密的Tx数据包如何继续传输,这对流有什么影响,因为没有握手协议告诉Tx Rx由于CRC错误而丢弃了一个数据包(如果有)?
如果对这些问题的解答以关于微型AES的进一步文档的形式存在,我将感谢与它的一些链接,因为所提供的注释假定人们已经熟悉AES等。
因此,这是对已经发表的评论/回复的进一步说明。基本上,Tx / Rx对具有预定义的数据包结构,其中包含一定的有效负载,标头CRC等,但我们称其为“数据包”。有效负载是我需要加密的内容,它固定为120个字节,无论在包中都不能协商。 因此,您要说的是,每次发送数据包时,Tx和Rx都需要更改每个数据包的随机数,并且Tx和Rx都需要在每次处理数据包时都使用相同的随机数?
假设我开始传输,并具有数据包(1),数据包(2)…数据包(n)等,然后在传输每个数据包时,我需要更新“计数器”,并且发射机和接收机都需要同步以便在会话中都使用相同的随机数?
当并且如果由于噪声或干扰,Tx / Rx系统失去同步可能会出现问题,并且随机数的两个独立计数器不再同步,并且在同一页面上-说话… 通常,一个会话平均不需要超过2 ^ 16个数据包,那么您能找到解决此问题的方法吗?就像我说的那样,因为有效载荷已经完整且充满了,因此对于每个单独的数据包发送不同的随机数是完全不可能的。
我认为,如果可以的话,也许可以给您一些启示,那就是通过GPS。假设每个Tx和Rx都具有一个GPS模块(情况就是如此),则可以从Tx和Rx上的GPS时钟中获取定时信息,因为两者都将独立接收,并且某种同步计数器可能会滚动到更新两者的随机数,比如说在一个会话中从0计数到2 ^ 16 ...您同意吗?因此,即使由于噪声/干扰,数据包被接收器丢失,计数器也会在后台以某种形式的可靠“滴答”形式继续更新随机数……
关于熵的来源,很明显,lampert电路将为本地运行的良好PRNG提供此功能,比如说会话为2 ^ 16包,但这在我的系统上尚不可用,但是如果我们决定进一步发展……
您对此有何看法? 问候
答案 0 :(得分:1)
我假设您所指的Tiny AES是tiny-AES-c(尽管您的代码与该代码有些不同;我无法找到定义了AES_ctx_set_key
的任何地方)。我认为当您说“ CRT模式”时,您是指CTR模式。
AES_ctx_init()的用途是什么,在安全链接的加密/解密会话开始时仅执行一次吗?
这将初始化内部数据结构。具体来说,它执行密钥扩展,该密钥扩展从主密钥创建必要的回合密钥。在该库中,看起来将在会话开始时调用一次以设置密钥和IV。
在CTR模式下,绝对不要在两个不同的消息上重用Key + Nonce(IV)组合,这一点至关重要。 (从技术上讲,CTR模式没有“ IV”。它具有“ nonce”,但它看起来与IV完全一样,并且在我见过的每个密码库中均以相同的方式传递。)如果需要重用随机数,您必须更改密钥。通常,这意味着您将必须在加密设备上保留一个持久的(即在系统重置期间)运行计数器,以跟踪上次使用的随机数。有多种方法可以安全地使用半随机随机数,但是您需要高质量的熵源,而嵌入式设备通常无法提供这种熵源。
如果您将NULL作为IV / nonce传递并重新使用密钥,则CTR模式几乎是一文不值的加密方案。
由于您需要能够干净整洁地丢弃数据包,因此您需要将随机数与每个数据包一起发送。随机数不是秘密;对于给定的密钥,它必须是唯一的。随机数为16个字节长。如果数据太多,一种常见的方法是在会话开始时交换随机数的前12个字节,然后使用后4个字节作为从0开始的计数器。如果会话长度可以大于2 ^ 32块,那么在用完值之后,您需要重置会话。
请记住,这里的“块”长16个字节,每个块都需要自己的随机数。要容纳120个字节,您可能会执行类似的操作,例如发送4个字节的起始计数器,然后为n,n + 1,n + 2,... n + 6附加7个块。
设计这种好方法有点复杂,而且很容易犯错并破坏您的加密技术。如果这很重要,您可能应该请有经验的人为您设计。我从事这种工作,但是我敢肯定您会找到很多人。
所以您要说的是,每次发送数据包时,Tx和Rx都需要更改每个数据包的随机数,并且Tx和Rx都需要在每次处理数据包时都使用相同的随机数? / p>
正确。 Tx端将确定随机数,Rx端将消耗它。尽管除了明确发送消息外,他们还可以通过其他方式进行协调,但前提是不要重复发送,并且他们始终同意。这是点击率模式的好处之一;它依赖于一个不一定要发送的“计数器”。
时钟很好,因为它不重复。棘手的部分是保持同步,同时绝对确定您不会重复使用随机数。如果每个随机数的时间窗口很大,则保持同步更容易。如果时间窗口很小,可以确保您永远不要重复使用随机数。将时钟源随机数与顺序计数器相结合可能是一个好方法。接收方仍然存在持续的同步问题,接收方需要尝试一些不同的计数器(或nonce + counters)以找到正确的计数器。但这应该是可能的。
请注意,同步假定存在一种区分有效明文和无效明文的方法。如果明文具有结构,则可以尝试一个随机数,如果输出乱码,请尝试另一个。但是,如果纯文本没有任何结构,那么您将面临一个大问题,因为您将无法同步。 “结构”是指“您能说出有效数据与随机噪声之间的区别吗?
使用时钟,只要您的窗口足够小,以至于您永远都不会重用开始的随机数,即使在重置期间,也可以避免使用PRNG。随机数不必一定是随机的。它永远无法重复。
请注意,如果您有一个4字节的计数器部分,那么您将拥有2 ^ 32个块,而不是2 ^ 16。