gpt4 book ai didi

c# - C++ 和 C# 与 Crypto 之间加密的互操作性

转载 作者:太空宇宙 更新时间:2023-11-04 11:32:26 25 4
gpt4 key购买 nike

我正在尝试在 Qt 项目中使用 Crypto++ 库在 C++ 中加密字符串,并在 Web 应用程序中在 C# 中解密该字符串。这是我的代码。

C++ 代码,使用 Crypto++ 库

std::string Crypter::encrypt(const std::string& str_in, const std::string& key, const std::string& iv)
{
std::string str_out;
CryptoPP::CFB_Mode<CryptoPP::AES>::Encryption encryption((byte*)key.c_str(), key.length(), (byte*)iv.c_str());
qDebug() << encryption.DefaultKeyLength();
qDebug() << encryption.DefaultIVLength();


CryptoPP::StringSource encryptor(str_in, true,
new CryptoPP::StreamTransformationFilter(encryption,
new CryptoPP::Base64Encoder(
new CryptoPP::StringSink(str_out),
false // do not append a newline
)
)
);
return str_out;
}

在这里调用函数

std::string str = "123456789012345";
std::string key = "01234567891234560123456789123456"; // 32 bytes
std::string iv = "0123456789123456"; // 16 bytes
std::string str_encrypted = c->encrypt(str, key, iv);
std::string str_decrypted = c->decrypt(str_encrypted, key, iv);
std::cout << "str_encrypted: " << str_encrypted << std::endl;
std::cout << "str_decrypted: " << str_decrypted << std::endl;

这段代码产生如下结果

Plain text: "123456789012345"
Encrypted value (base64): 3Qo/6hWctRiID3txA9nC

我在这里用 C# 编写了相同的代码

    private void button1_Click(object sender, EventArgs e)
{
string strOutput = Encrypt("123456789012345");
Debug.WriteLine("Encrypted value is: " + strOutput);
}

private string Encrypt(string clearText)
{
byte[] clearBytes = Encoding.ASCII.GetBytes(clearText + "\0");

using (Aes encryptor = Aes.Create("AES"))
{
encryptor.BlockSize = 128;
encryptor.KeySize = 128;
encryptor.Mode = CipherMode.CFB;
encryptor.Key = Encoding.ASCII.GetBytes("01234567891234560123456789123456");
encryptor.IV = Encoding.ASCII.GetBytes("0123456789123456");
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
byte[] bt = ms.ToArray();
clearText = Convert.ToBase64String(bt);
}
}
return clearText;
}

产生以下结果

Encrypted value is: 3YklwM2vG20ZmkOT029jTTL7FlSZHrh0RfvaT1FFa2k=

有人可以告诉我我错过了什么吗?从两种语言获得相似输出的正确方法是什么。

我的目标是在 C++ 中加密一个值并在 C# 中解密该值。

编辑

我做了一些改变。

将 Hello world 替换为 123456789012345将编码从 utf 更改为 Ascii在 C# 字符串的末尾添加了一个空字节改变模式为CFB

我也用新结果编辑了原始结果

不幸的是,同样这样做之后,两个字符串都不匹配。

我已确保两个输入相同。

最佳答案

您的 C++ 代码是根据 std::string 编写的。这很可能是保存在 ANSI 代码页下编码的文本。当您将它传递给 CryptoPP::StringSource 时,我希望它直接处理该文本的字节,而无需将其转换为任何其他编码。

您的 C# 正在传递 Encoding.Unicode.GetBytes 的结果。这意味着加密是针对 UTF-16 编码数据的字节进行的。

由于编码不同,字节表示也不同。那么由于字节不同,加密后的结果也不同。

您需要让两段代码在同一方案下工作。

如果您只想处理 ANSI(或什至只是 ASCII)字符(给定您的 C++ 代码可能就是这种情况),那么您可以修改 C# 代码以使用 Encoding.Default.GetBytes(或者可能是 Encoding.ASCII.GetBytes)以获取明文的字节。


编辑

进一步看,您的 C++ 代码使用 CryptoPP::CFB_Mode,而您的 C# 代码使用 encryptor.Mode = CipherMode.CBC;。这些模式需要匹配,否则算法将以不同方式应用。

您可能需要检查其他属性,例如填充,以确保两者在同一方案下工作。

关于c# - C++ 和 C# 与 Crypto 之间加密的互操作性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24214716/

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