文档 技术细节 密钥文件

# 密钥文件

VeraCrypt密钥文件是一种其内容会与密码相结合的文件。用户可以使用任何类型的文件作为VeraCrypt密钥文件。用户还可以使用内置的密钥文件生成器来生成密钥文件，该生成器利用VeraCrypt随机数生成器（RNG）生成具有随机内容的文件（更多信息，请参阅 随机数生成器部分）。

密钥文件的最大大小没有限制；但是，仅处理其前1,048,576字节（1 MiB）（由于处理超大文件会带来性能问题，所有剩余字节将被忽略）。用户可以提供一个或多个密钥文件（密钥文件的数量没有限制）。

密钥文件可以存储在符合PKCS - 11标准[23]的安全令牌和受多个PIN码保护的智能卡上（可以使用硬件PIN键盘或通过VeraCrypt图形用户界面输入这些PIN码）。

符合EMV标准的智能卡数据可以用作密钥文件，请参阅 EMV智能卡章节。

密钥文件使用以下方法进行处理并应用于密码：

1. 设P为用户提供的VeraCrypt卷密码（可以为空）
2. 设KP为密钥文件池
3. 设kpl为密钥文件池KP的大小，以字节为单位（64，即512位）；

   kpl必须是哈希函数H输出大小的倍数

4. 设pl为密码P的长度，以字节为单位（在当前版本中：0 ≤ pl ≤ 64）
5. 如果kpl > pl，则在密码P后面追加（kpl - pl）个零字节（因此pl = kpl）
6. 用kpl个零字节填充密钥文件池KP。
7. 对每个密钥文件执行以下步骤：
   1. 将密钥文件池游标位置设置为池的开头
   2. 初始化哈希函数H
   3. 逐个加载密钥文件的所有字节，并对每个加载的字节执行以下步骤：
      1. 使用哈希函数H对加载的字节进行哈希处理，而不初始化哈希，以获得中间哈希（状态）M。不要完成哈希计算（状态将保留用于下一轮）。
      2. 将状态M拆分为单个字节。
         例如，如果哈希输出大小为4字节，（T0 || T1 || T2 || T3） = M
      3. 将这些字节（在步骤7.c.ii中获得）逐个写入密钥文件池，使用模28加法运算（而不是替换池中旧值），写入位置为池游标的位置。写入一个字节后，池游标位置前进一个字节。当游标到达池的末尾时，其位置将设置为池的开头。
8. 使用以下方法将密钥文件池的内容应用于密码P：
   1. 将密码P拆分为单个字节B0...Bpl - 1。
      请注意，如果密码比密钥文件池短，则在步骤5中密码已用零字节填充到池的长度（因此，此时密码的长度始终大于或等于密钥文件池的长度）。
   2. 将密钥文件池KP拆分为单个字节G0...Gkpl - 1
   3. 对于0 ≤ i < kpl，执行：Bi = Bi ⊕ Gi
   4. P = B0 || B1 || ... || Bpl - 2 || Bpl - 1
9. 应用了密钥文件池内容后的密码P现在将传递给头密钥派生函数PBKDF2（PKCS #5 v2），该函数使用用户选择的加密安全哈希算法（例如SHA - 512）对其进行处理（连同盐值和其他数据）。有关更多信息，请参阅 头密钥派生、盐值和迭代次数部分。

哈希函数H的作用仅仅是进行扩散[2]。使用CRC - 32作为哈希函数H。请注意，CRC - 32的输出随后会使用加密安全哈希算法进行处理：密钥文件池的内容（除了使用CRC - 32进行哈希处理外）会应用于密码，然后将该密码传递给头密钥派生函数PBKDF2（PKCS #5 v2），该函数使用用户选择的加密安全哈希算法（例如SHA - 512）对其进行处理（连同盐值和其他数据）。所得值用于形成头密钥和辅助头密钥（XTS模式）。

下一部分 >>