gpt4 book ai didi

c# - 发送C#AES加密字符串给CyptoPP C++程序解密

转载 作者:太空宇宙 更新时间:2023-11-04 12:14:20 24 4
gpt4 key购买 nike

我正在尝试通过 tcp 连接从 C# 程序向 C++ 程序发送加密字符串。当 c++ 程序尝试解密字符串时,它在 crypto++ 中崩溃。我可以在调试器中看到字符串大部分已解码但未正确终止。例如,如果我发送“Hello world”,它会被解密为“Hello world%%@#$@#”(最后是垃圾)

我是这样加密的

           //Create byte arrays to hold original, encrypted, and decrypted data.
byte[] dataToEncrypt = ByteConverter.GetBytes(data);

byte[] key = new byte[16];
for (int i = 0; i < 16; ++i)
{
key[i] = 1;
}

byte[] iv = new byte[16];
for (int i = 0; i < 16; ++i)
{
iv[i] = 1;
}


RijndaelManaged myRijndael = new RijndaelManaged();

myRijndael.Key = key;
myRijndael.IV = iv;
byte[] encrypted = encryptStringToBytes_AES(data, myRijndael.Key, myRijndael.IV);

// sends the byte array via active tcp connection
_transport.SendEncryptedData(encrypted);


static byte[] encryptStringToBytes_AES(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");

// Declare the stream used to encrypt to an in memory
// array of bytes.
MemoryStream msEncrypt = null;

// Declare the RijndaelManaged object
// used to encrypt the data.
RijndaelManaged aesAlg = null;

try
{
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.Key = Key;
aesAlg.IV = IV;

// Create an encrypto to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

// Create the streams used for encryption.
msEncrypt = new MemoryStream();
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
}
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
aesAlg.Clear();
}

// Return the encrypted bytes from the memory stream.
return msEncrypt.ToArray();
}

这是使用 Crypto++ 解密的 C++ 端

     byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ];
byte iv[ CryptoPP::AES::BLOCKSIZE ];
::memset( key, 0x01, CryptoPP::AES::DEFAULT_KEYLENGTH );
::memset( iv, 0x01, CryptoPP::AES::BLOCKSIZE );

std::string decryptedtext;


CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );


CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decryptedtext ) );

// CRASHES IN .PUT(...)
stfDecryptor.Put( reinterpret_cast<const unsigned char*>(data ), len + 1);
stfDecryptor.MessageEnd();

最佳答案

您的问题是因为 2 件事中的 1 件事,也许是两件事。

  1. C# 流编写器未写出空字节。当 C++ 代码读入数据时,字符串不是空终止的。我尚未测试您提供的代码,但这似乎是预期的行为。

  2. 假定的填充方法(或缺少填充方法)在 C# 实现和 Crypto++ 实现之间可能不同。 CBC 模式下的 AES 只能加密或解密 block 大小的倍数的 block 。在 AES 中, block 大小为 128 位或 16 字节。

维基百科对各种分组密码模式有很好的解释 here . CBC 的典型填充是 PKCS7,描述为 here .

我不太了解这两种实现的内部结构,无法知道填充的默认方法是什么,或者是否将其留给用户。

关于c# - 发送C#AES加密字符串给CyptoPP C++程序解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8388945/

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