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

标签 c# c++ encryption crypto++

我正在尝试通过 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/

相关文章:

c# - 如何在声明中有条件地设置基类

c# - 将用户控件拖放到 VS 设计器时发生 TypeLoadException

c++ - 如何创建一个自动启动的 C++ 程序

c# - Oxyplot:对数干图是颠倒的

c# - 尝试捕获最后的问题

c++ - CodeBlocks 13.12 使用什么 c++ 版本?

c++ - Arduino SHA1-HMAC 和 base64 编码与 Python 之间的对话问题

java - C++/Openssl 从编码字节中获取 RSA key (由 java 编码)

android - PBKDF2 与 Android 上的 SHA256

java - Javascript 和 Java 中的 RSA 代码