加密初始化向量

Rah*_*hul 4 c c++ encryption pascal initialization-vector

使用aes_cfb_encryptaes_cfb_decrypt函数,我有以下问题.

  1. 什么是加密中的unsigned char*iv(初始化向量).
  2. 是否需要保留*iv进行解密.
  3. 每次我加密一个数据块*iv被修改,我有什么用这个修改*iv.
  4. 我正在加密大约100mb的大文件,并且第一次传递随机*iv,我是否必须在循环的其余部分使用相同的*iv,或者我必须使用上次调用时更新的*iv加密块.

  5. 最后,我正在处理结构化文件,所以我必须使用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]);
Run Code Online (Sandbox Code Playgroud)

aes_cfb_encrypt

Who*_*aig 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.
Run Code Online (Sandbox Code Playgroud)

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))
Run Code Online (Sandbox Code Playgroud)

注意:上面的"+"表示将先前的密码块应用于下一个明文块.它不应被视为数学加法.把它想象成"与......结合".

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用于下一次加密,这在您考虑反馈或链接如何用于块模式加密时非常有意义.你不应该反复使用相同的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.
Run Code Online (Sandbox Code Playgroud)

同样,如果您将每个结构独立加密和存储为单一加密,那么您的API可能会为您解决部分问题.

有关对称AES的更多信息,请参阅Wiki上AES条目.有关CFB分组密码模式的信息,请参阅同一站点上的分组密码操作模式一文.

我希望这有帮助.做一些功课,最重要的是,准确了解你的API 如何工作的,不幸的是,这是我无法帮助你的.