gpt4 book ai didi

c# - 为什么我在使用 DPAPI 加密时得到不同的输出?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:36:17 27 4
gpt4 key购买 nike

我在 C++ 中使用 DPAPI 来加密我需要存储在文件中的一些数据。问题是我需要从 C# 读取该文件,所以我需要能够:

C++ 加密,C++ 解密(运行良好)

C# 加密,C# 解密(运行良好)

C++ 加密,C# 解密,反之亦然(不工作)

在 C# 中,我使用 DllImport 来 pInvoke 方法 CryptProtectData 和 CryptUnprotectData,并按照说明实现它们 here .我知道在 C# 中,我可以使用 ProtectedData 类中包含的方法,但我正在以这种方式(使用 DllImport )进行操作,以确保两种代码(c++ 和 c#)的外观和工作方式几乎相同。

现在奇怪的是,即使两个代码看起来一样,我也会得到不同的输出,例如这个文本:

“纯文本”

在 C++ 中我得到:

01 00 00 00 D0 8C 9D DF 01 15 D1 11 8C 7A 00 C0 4F C2 97 EB 01 00 00 00 2E 6F 88 86 E6 16 9B 4F 9B BF 35 DA 9F C6 EC 12 00 00 00 0 0 02 02 00 00 00 0 0 02 00 00 00 03 66 00 00 A8 00 00 00 10 00 00 00 93 06 68 39 DB 58 FE E9 C4 1F B0 3D 7B 0A B7 48 00 00 00 00 04 80 00 00 A0 00 00 00 4 6 E 00 05 0D 4A 34 15 97 DC 5B 1F 6C A4 19 D9 10 00 00 00 F5 33 9F 55 49 94 26 54 2B C8 CB 70 7B FE EC 96 14 00 00 00 C5 23 DA BA C8 23 6C 0B B3 88 60 95 29 AE 76 A7 63 E4

在 C# 中我得到:

01 00 00 00 D0 8C 9D DF 01 15 D1 11 8C 7A 00 C0 4F C2 97 EB 01 00 00 00 2E 6F 88 86 E6 16 9B 4F 9B BF 35 DA 9F C6 EC 12 00 00 00 0 0 02 02 00 00 00 0 0 02 00 00 00 03 66 00 00 A8 00 00 00 10 00 00 00 34 C4 40 CD 91 EC 94 66 E5 E9 23 F7 9E 04 9C 83 00 00 00 00 04 80 00 00 A0 00 00 02 E 10 40 10 10 26 72 26 0A D1 11 1D 4D EF 13 1D B2 6F 10 00 00 00 81 9D 46 37 D1 68 5D 17 B8 23 78 48 18 ED 06 ED 14 00 00 00 E4 45 07 1C 08 59 D 4339 8 0B 71 35 39 05 C4 BB

如您所见,前几个字符相同,但其余字符不同,所以如果有人知道为什么会发生这种情况,我将不胜感激。

谢谢。

C++ 代码:


value = "plain text";
DATA_BLOB DataIn;
DATA_BLOB DataOut;

BYTE *pbDataInput =(BYTE *)(char*)value.c_str();
DWORD cbDataInput = strlen((char *)pbDataInput)+1;
DataIn.pbData = pbDataInput;
DataIn.cbData = cbDataInput;

CryptProtectData(&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))

C# 代码:

(您可以看到我的 C# 代码看起来如何 here,因为与此 Microsoft 示例中的代码相同)

最佳答案

如果您可以发布您的 C++ 和 C# 代码,将会有所帮助。也许有一些细微的参数差异或类似的东西。例如,您应该确保 pOptionalEntropy 参数相同(或将其设置为 NULL 以测试这是否是错误源)。另外,请确保尝试在同一台 PC 上加密和解密:

[...]decryption usually can only be done on the computer where the data was encrypted

(来源:MSDN)

编辑:对您发布的代码和来自 MSDN 的 C# 版本的一些评论(部分内容如下):

public byte[] Encrypt(byte[] plainText, byte[] optionalEntropy) {
[...]
int bytesSize = plainText.Length;
plainTextBlob.pbData = Marshal.AllocHGlobal(bytesSize);
plainTextBlob.cbData = bytesSize;
Marshal.Copy(plainText, 0, plainTextBlob.pbData, bytesSize);
[...]
dwFlags = CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN;
[...]
if(null == optionalEntropy)
{//Allocate something
optionalEntropy = new byte[0]; // Is copied to entropyBlob later
}
[...]
retVal = CryptProtectData(ref plainTextBlob, "", ref entropyBlob,
IntPtr.Zero, ref prompt, dwFlags,
ref cipherTextBlob);
[...]
}

这里再次显示您的 C++ 代码:

[...]
BYTE *pbDataInput =(BYTE *)(char*)value.c_str();
DWORD cbDataInput = strlen((char *)pbDataInput)+1;
[...]
CryptProtectData(&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))

参数不匹配,我认为这是差异的根源。

首先是旗帜。 C# 代码使用 dwFlags != 0,您的 C++ 代码使用 dwFlags = 0,所以这显然是不同的。

我不确定熵。如果您没有传递 optionalEntropy = null,那是不同的,但如果它为 null,则会有一个“new byte[0]”赋值,我不确定这会产生什么,但我认为您至少应该尝试一下将 IntPtr.Zero 而不是 entropyBlob 传递给 CryptProtectData 以与 C++ 代码匹配。

最后但同样重要的是,您的 C++ 代码包含分隔 C 字符串的尾随 NUL,我不知道此处使用的加密是如何工作的,但如果一个字节不同,则有一些加密会给您非常不同的输出(或者你有一个像这种情况一样的字节),所以你应该在 C# 代码中包含一个终止 NUL 或在 C++ 代码中删除它。

关于c# - 为什么我在使用 DPAPI 加密时得到不同的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1447053/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com