gpt4 book ai didi

c# - 从 C# 调用时 CFB 模式的截断输出

转载 作者:行者123 更新时间:2023-11-30 02:45:40 25 4
gpt4 key购买 nike

我有一个非常烦人的问题,两天都无法解决。我有一个 encrypt() 方法,它使用用 C++ 编写的 Crypto++ 库。该方法实现如下:

string CRijndaelHelper::Encrypt(string text)
{
CFB_Mode< AES >::Encryption e;
e.SetKeyWithIV(_key, sizeof(_key), _iv);

string cipher, encoded;

// CFB mode must not use padding. Specifying
// a scheme will result in an exception
StringSource ss(text, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
));

return cipher;
};

当我在 native 环境中调用此方法时,它运行良好,可以毫无问题地加密整个 26Kb xml 字符串。

最终我不得不在 C# 代码中实现加密,为此我在 native dll 中编写了以下包装代码以供以后与 PInvoke 一起使用:

extern "C"
API_EXPORT char* _cdecl encrypt(char* contents)
{
string cont(contents);
CRijndaelHelper rij;
string transformedText = rij.Encrypt(cont);
return marshalReturn(transformedText);
}

虽然 PInvoke 部分如下所示:

[DllImport("EncryptDecrypt.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string encrypt([MarshalAs(UnmanagedType.LPStr)] string contents);

一切看起来都很完美,只是我在 transformedText 变量中只加密了前 540 个字节,仅此而已。

请指教。

最佳答案

您的根本问题是您正在处理错误的类型。加密适用于字节数组,而不适用于文本。您需要停止使用 stringchar* 等。您需要在非托管代码中使用unsigned char*,在托管代码中使用byte[]

你可能很难接受这个建议,但我还是提供了。除了零字节被视为空终止符的问题(截断的原因)之外,您当前的方法只是忽略了文本编码问题。你不能那样做。

您可能有充分的理由希望将一个字符串转换为另一个字符串。这很好,但是转换的加密部分需要对字节数组进行操作。处理文本到文本加密的方法是使用转换链。加密时的转换是这样运行的:

  1. 使用明确定义的编码将字符串转换为字节数组。例如,UTF-8。
  2. 加密字节数组,输出另一个字节数组。
  3. 使用例如 base64 将此加密的字节数组编码为文本。

这尊重加密对字节数组进行操作的事实,以及对文本编码的明确说明。

在相反的方向上,您可以反转步骤:

  1. 将 base64 解码为加密的字节数组。
  2. 解密这个字节数组。
  3. 使用UTF-8对解密后的字节数组进行解码,得到原始字符串。

关于c# - 从 C# 调用时 CFB 模式的截断输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24237654/

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