使用aes_cfb_encrypt
和aes_cfb_decrypt
函数,我有以下问题。
我正在加密大约100mb的大文件,并且第一次传递随机 * iv ,我是否必须使用相同的 * iv 对于循环的其余部分,或者我必须使用上次调用加密块时更新的 * iv 。
最后,我正在处理结构化文件,所以我必须使用 Sizeof(struct)作为缓冲区的长度或必须使用 sizeof(struct)* 8 作为加密或解密缓冲区的长度。 请指导..
AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
答案 0 :(得分:8)
在回答您的问题时,请注意以下事项:
PT(x) = Plain Text representation of 'x'
CT(x) = Cipher Text representation of 'x'
Bn = Logical Data Block 'n' in a sequence of multiple blocks.
<强> 1。什么是IV?
IV是初始化向量的简短表示法。它用于对称块加密算法,在所谓的链式或反馈模式下执行加密。在任一种情况下,先前的加密数据块被用作一段功能数据“goo”以改变下一个要加密的数据块。每个连续的加密数据块都被提供给先前已加密的数据块作为其要使用的粘性块。但是明文的第一个块呢? 它用于其特殊酱汁的是什么?答:IV提供给功能。图示,它看起来如下:
CT(B1) = Encrypt(IV + PT(B1))
CT(B2) = Encrypt(CT(B1) + PT(B2))
CT(B3) = Encrypt(CT(B2) + PT(B3))
...
CT(Bn) = Encrypt(CT(Bn-1) + PT(Bn))
注意:上面的“+”表示将先前的密码块应用于下一个明文块。 不被认为是数学加法。把它想象成“结合”。
IV 的大小必须与正在使用的对称算法的块大小相同。 AES-128-CFB和AES-256-CFB都使用128位块大小(16字节)。因此,对于此问题,您的IV应该是16字节的随机goo,并且应该使用安全的符合FIPS的随机源算法在加密端生成。
<强> 2。是否需要保留IV进行解密?
是的,但不一定是您可能首先想到的时尚。第一个IV(由你提供)必须以某种方式保留。传统上,它会被发送到您认为应该的位置;作为第一块加密数据。这通常会吓坏人们,他们认为“但如果我发送带有数据的IV,它就不那么安全了,是吗?”这样想吧。 你发送了多少“IV”?请记住,每个数据块都使用之前的加密数据块加密为IV。因此,您实际上是在发送整个IV流,每个加密块都是IV用于下一个加密块,等等。初始IV在您的输出密文中是一个数据表示问题,但它的最终位置与这个问题。 必须保留。作为输出流的一部分,您的API可能会为您执行此操作(事实上,这并非罕见)。
第3。每当我加密一个数据块时* iv被修改,我对这个修改过的* iv怎么办?
我不熟悉您正在使用的API,但听起来您已经将IV用于 next 加密,这在您考虑反馈时是非常有意义的链接适用于块模式加密。你不应该反复使用相同的IV。使用最后返回的那个作为下一个。由于您的API正在修改IV,因此您可能需要做的唯一事情就是在发送之前将初始 IV保留在其他位置。我会将第一个密文块与你的IV进行比较。如果它们不相同,您可能需要在数据流中发送IV,然后密码文本链,并让接收方知道第一个块是解密的IV。
<强> 4。我正在加密大约100mb的大文件,并且第一次传递随机* iv,我是否必须在循环的其余部分使用相同的* iv,或者我必须使用上次调用时更新的* iv加密块。
见(3)。对每个连续的块使用更新的IV。
<强> 5。最后,我正在处理一个结构化文件,所以我将sizeof(struct)作为缓冲区的长度,或者必须使用sizeof(struct)* 8作为加密或解密的缓冲区长度。?
使用结构的大小以字节为单位(不是位)。 C / C ++ sizeof(yourstruct)
应该为您计算,但请注意,如果您将每个结构加密为一个独立的实体(而不是一个整体中的整个文件),每个加密将携带最少量的数据添加到(a)用于该结构的IV,以及(b)将最后一个块填充到偶数块边界,假设您正在使用PKCS5填充。因此,加密结构的确切大小为:
IV + ((sizeof(struct) + 15)/16)*16) bytes.
同样,如果您将每个结构独立加密和存储为单一加密,那么您的API可能会为您解决部分问题。
有关对称AES的更多信息,请参阅AES entry on Wiki。有关CFB分组密码模式的信息,请参阅同一站点上的Block Cipher Modes of Operation文章。
我希望这会有所帮助。做一些功课,最重要的是,学习完全你的API是如何工作的,不幸的是,这是我无法帮助你的。
答案 1 :(得分:1)
加密系统中的初始化向量(IV)是一个随机值,它作为加密系统初始化的一部分包含在内,以确保如果相同的数据被多次加密,它总是看起来不同。这是安全加密系统的要求,以确保查看多个不同加密消息的攻击者无法轻易确定这些消息中的任何两个是否相同。理想情况下,IV应该完全随机选择。
您不需要保留IV进行解密。通常,IV以明文与加密数据一起发送。这不是安全问题 - 它是设计的。
在每次加密迭代时都会更改IV,因为内部加密系统会迭代地将数据块密码应用于数据,然后使用该密码的输出结合一些额外数据作为下一个应用程序的新IV分组密码。然后根据需要多次迭代该过程。我怀疑(但不确定)将IV传回给您,以便您可以加密以前从中断过的数据。 你一定要仔细检查一遍!
至于是否使用你的结构的大小或八倍 - 我不能说没有看到更多的代码。但是,您可能应该提供要加密的总字节数,因此如果要加密结构的八个副本,则传入sizeof
结构的八倍。
希望这有帮助!