首页 > 解决方案 > 前 16 个字节的 IV 从解密的字符串中删除?C#/Python3

问题描述

我想知道为什么我的所有字符串的前 16 个字节都被加密,然后在被解密时丢失了,如果可能的话如何解决这个问题。我在 c# 中像这样加密

        public static string EncryptString(string b_key, string plainText)  
        {  
            byte[] iv = new byte[16];  
            byte[] array;  
  
            using (Aes aes = Aes.Create())  
            {  
                aes.Key = Convert.FromBase64String(b_key);  
                aes.IV = iv;  
  
                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);  
  
                using (MemoryStream memoryStream = new MemoryStream())  
                {  
                    using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))  
                    {  
                        using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))  
                        {  
                            streamWriter.Write(plainText);
                        }  
  
                        array = memoryStream.ToArray();  
                    }  
                }  
            }  
  
            return Convert.ToBase64String(array);  
        }  

并像这样在python3中解密

            enc = base64.b64decode(self.text)
            iv = enc[:16]
            cipher = AES.new(self.key, AES.MODE_CBC, iv)
            plain_text = cipher.decrypt(enc[16:])
            plain_text = self.dePKCS7_padding(plain_text)
            return plain_text

可以读取前 16 个字节吗?或必须用于加密。我也希望它加密安全,但前 16 个字节很重要,这可能吗?无论如何要在 c# 或 python3 中解决这个问题?

标签: c#python-3.xencryptionaes

解决方案


根据@MichaelFehr 和@user9014097 的评论和输入中的讨论,我想出了以下代码。

在此代码中IV,AES 将在AES.Create()调用时创建随机值。同样将用于加密值的结果。

decryptString 方法将从iv传入的加密字符串中捕获值,并在解密字符串时将其分配给 AES。

    public static string EncryptString(string b_key, string plainText)
    {
        byte[] array;

        using (Aes aes = Aes.Create())
        {
            aes.Key = Convert.FromBase64String(b_key);

            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

            using (MemoryStream memoryStream = new MemoryStream())
            {
                // Adding aes.IV to the stream's start.
                memoryStream.Write(aes.IV);
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
                    {
                        streamWriter.Write(plainText);
                    }
                }
                array = memoryStream.ToArray();
            }
        }

        // The final encrypted outcome will be aes.IV+encryptedtext.
        return Convert.ToBase64String(array);
    }

    public static string DecryptString(string key, string cipherText)
    {
        //input is iv+encrypted text, convert them to byte array.
        byte[] buffer = Convert.FromBase64String(cipherText);

        // byte array for iv
        byte[] iv = new byte[16];

        // byte array for rest of the cipher text.
        byte[] cipherBuffer = new byte[buffer.Length - 16];

        // copy first 16 bytes from the cipher text to iv.
        Buffer.BlockCopy(buffer, 0, iv, 0, 16);


        // copy rest of the cipher text to the cipher buffer to be decrypted.
        Buffer.BlockCopy(buffer, 16, cipherBuffer, 0, buffer.Length - 16);

        using (Aes aes = Aes.Create())
        {
            aes.Key = Convert.FromBase64String(key);
            aes.IV = iv;

            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

            using (MemoryStream memoryStream = new MemoryStream(cipherBuffer))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader streamReader = new StreamReader(cryptoStream))
                    {
                        return streamReader.ReadToEnd();
                    }
                }
            }
        }
    }

在编写上面的代码时,我有以下假设。

  1. 长度IV为 16。
  2. Python 代码(上面共享)不需要根据某些特定字符拆分输入文本。它将前 16 个字节作为IV值,其余字节作为密文。

我能够使用上述方法在 C# 中成功加密和解密值。

我无法解密 python 代码中的值,因为我几乎不知道如何使用 python。

您可以在 python 中测试上述加密的结果来解密它。让我知道它是否按预期工作。

我希望这能帮助你解决你的问题。


推荐阅读