0

使用 Windows 数据保护 API,可以加密内存中的数据,如以下代码所示:

byte[] toEncrypt = UnicodeEncoding.ASCII.GetBytes("ThisIsSomeData16");

Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt));
Console.WriteLine("Encrypting...");

// Encrypt the data in memory.
EncryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon);

Console.WriteLine("Encrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt));
Console.WriteLine("Decrypting...");

// Decrypt the data in memory.
DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon);

Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt));

请参阅此处的 Microsoft 参考:https ://msdn.microsoft.com/en-us/library/ms995355.aspx

但是,此示例中的加密数据与原始数据的大小相同。有没有办法利用 DPAPI 加密数据而不泄露原始文件的文件大小?例如,将生成的密文隐藏在密钥内的“随机”位置,尽可能使用一次性密码?

4

1 回答 1

0

如果您加密 DPAPI blob 中的数据,然后解密该 blob,您将获得完全相同的数据。这就是它的全部意义所在。如果您查看加密的 DPAPI blob 并且系统使用 AES(从 Win7 开始是默认设置),那么任何人都可以推断出秘密的大致长度,因为其中的加密数据的大小是最接近的倍数块大小到实际长度。例如,如果密钥长度为 17 个字节,则 DPAPI 提供者加密这些字节,然后加密 15 个字节,值为 0xF 以创建两个块供 AES 加密(并在解密时剥离这些字节)。因此,只需查看 DPAPI 数据中的大小,我们就可以看到秘密是 16-31 字节长。

如果这会是一个问题,您将不得不将自己的秘密包装在自己的填充中:创建为要保护的数据:“秘密长度”秘密“随机内容”,并将其放入 DPAPI。任何人都可以推断出这个数据的大致长度(最多 16 个字节),但不能推断出实际秘密的长度,当然,除了微不足道的上限。当合法用户取回 DPAPI blob 的解密后,他可以从长度字段中推断出秘密(当然,它本身应该具有已知的固定长度)。DPAPI 确保数据不会被篡改(它使用 HMAC),因此您相信该数据是正确的。

您还可以使用您知道不会出现在要保护的密钥中的任何字节,并将其用作密钥数据末尾的标记字节。例如,如果它是 C 字符串,则为 0x0。但我认为增加长度更安全。

于 2017-03-05T10:02:52.570 回答