AESCrypt如何处理file format 2的初始化向量(IV)?
在生成文件时似乎无法指定IV ...所以我假设IV在密文旁边未加密存储?
它是open source。我快速浏览了一下代码,并没有立即清楚。
This link references an IV1 ......但它还不完全清楚。 IV1来自哪里?
答案 0 :(得分:2)
我只是做了一些环顾四周,而且我在很大程度上理解它。我会尽我所能地回答你的问题。
1)AESCrypt每次加密使用2个IV。它们有一个密钥,用于加密大部分消息的IV对,它们是Key2和IV2,它们还有一个密钥,IV对仅用于加密Key2和IV2,它们被称为Key1和IV1。 Key1当然不是加密文件的一部分,但是IV1确实存储在您链接的灰色框底部附近的16个八位字节中。紧接着的48个八位字节是加密的Key2和IV2。 IV(特别是IV1)可以不加密。它是几乎不可能使相同的16字节数据块每次出现在密文中时看起来都一样。但是IV根本没有必要保密。我实际上对他们保持IV2秘密(加密)感到惊讶,但他们这样做并没有什么害处。
2)是的,我想我已经回答了这个,但IV1在每格式2规范的文件的16个八位字节块中未加密,并且IV2在48个八位字节之后用Key2加密。
3& 4我会一起回答。您可能已经看过IV2的函数,它只是一个直接生成字节的随机函数。 IV1以更复杂的方式生成。我会在这里发布最相关的代码。
因此,如果您仔细查看,该程序会抓取它可以在网络上找到的设备。然后它遍历它们,寻找一个可以使用的MAC地址。如果找不到它可以使用的,它使用DEFAULT_MAC,它是程序中其他地方定义的常量,如数组{0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}。
现在它以当前日期和时间为单位,并用原始IV填充8个字节。然后它使用它找到的任何MAC并使用它来填充相同原始IV阵列中的更多字节。
一旦完成,它会将此原始数组发送到DigestRandomBytes方法,其中,根据代码(此处不包含该代码块),该方法重复循环256次获取加密安全随机字节,然后使用SHA对它们进行哈希处理-256。关注我的一件事 - 只有一点,授予 - 是我没有看到MAC和日期时间滴答字节如何在DigestRandomBytes方法中存活或者根本无法增加其输出的熵。它们被发送到DigestRandomBytes方法,但似乎丢弃它们并用随机字节替换它们,并且这样做了256次。
无论如何,是的,IV1是随机生成的。
private byte[] GenerateIv1()
{
byte[] iv = new byte[IV_SIZE];
long time = DateTime.Now.Ticks;
byte[] mac = null;
/**********************************************************************
* *
* NOTE: The time and mac are COMPONENTS in the random IV input. *
* The IV does not require the time or mac to be random. *
* *
* The mac and time are used to INCREASE the ENTROPY, and *
* DECOUPLE the IV from the PRNG output, in case the PRNG *
* has a defect (intentional or not) *
* *
* Please review the DigestRandomBytes method before *
* INCORRECTLY ASSUMING that the IV is generated from *
* time and mac inputs. *
* *
***********************************************************************/
try
{
System.Net.NetworkInformation.NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
for (int i = 0; i < interfaces.Length; i++)
if (i != System.Net.NetworkInformation.NetworkInterface.LoopbackInterfaceIndex)
{
mac = interfaces[i].GetPhysicalAddress().GetAddressBytes();
break;
}
}
catch
{
//Not much to do, just go with default MAC
}
if (mac == null)
mac = DEFAULT_MAC;
for (int i = 0; i < 8; i++)
iv[i] = (byte)((time >> (i * 8)) & 0xff);
Array.Copy(mac, 0, iv, 8, Math.Min(mac.Length, iv.Length - 8));
return DigestRandomBytes(iv, 256);
}