Search code examples
c#cryptographyencryption-symmetrichybridencryption-asymmetric

Hybrid cryptography. Length of the data to decrypt is invalid


I am getting above mentioned error during a hybrid cryptography implementation.

as per https://en.wikipedia.org/wiki/Hybrid_cryptosystem

I am just stucked at the last step

My code is

 private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                CspParameters cspParams = new CspParameters { ProviderType = 1 };
                RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(2048, cspParams);
                string publicKey =lblPublicKey.Text = Convert.ToBase64String(rsaProvider.ExportCspBlob(false));
                string privateKey = lblPrivateKey.Text= Convert.ToBase64String(rsaProvider.ExportCspBlob(true));
                string symmericKey = txtBoxSymmetricKey.Text = "Kamran12";
                txtEncryptedData.Text = EncryptData(txtInputData.Text, symmericKey);
                txtBoxEncryptedSymmetricKey.Text = RSA_Encrypt(symmericKey, publicKey);



                txtBoxDescryptedSymmetricKey.Text = RSA_Decrypt(txtBoxEncryptedSymmetricKey.Text, privateKey);
                txtDecryptedData.Text = DecryptData(txtEncryptedData.Text, txtBoxDescryptedSymmetricKey.Text); //getting error length of the data to decrypt is invalid
            }
            catch (Exception exc)
            {

            }

        }

        public static string RSA_Decrypt(string encryptedText, string privateKey)
        {
            CspParameters cspParams = new CspParameters { ProviderType = 1 };
            RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
            rsaProvider.ImportCspBlob(Convert.FromBase64String(privateKey));
            var buffer = Convert.FromBase64String(encryptedText);
            byte[] plainBytes = rsaProvider.Decrypt(buffer, false);
            string plainText = Encoding.UTF8.GetString(plainBytes, 0, plainBytes.Length);
            return plainText;
        }

        public static string RSA_Encrypt(string data, string publicKey)
        {
            CspParameters cspParams = new CspParameters { ProviderType = 1 };
            RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
            rsaProvider.ImportCspBlob(Convert.FromBase64String(publicKey));
            byte[] plainBytes = Encoding.UTF8.GetBytes(data);
            byte[] encryptedBytes = rsaProvider.Encrypt(plainBytes, false);
            return Convert.ToBase64String(encryptedBytes);
        }



        public string EncryptData(string data, string key)
        {
            string encryptedData = null;
            byte[] buffer = Encoding.UTF8.GetBytes(data);
            DESCryptoServiceProvider desCryptSrvckey = new DESCryptoServiceProvider
            {
                Key = new UTF8Encoding().GetBytes(key)
            };
            desCryptSrvckey.IV = desCryptSrvckey.Key;
            using (MemoryStream stmCipherText = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(stmCipherText, desCryptSrvckey.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(buffer, 0, buffer.Length);
                    cs.FlushFinalBlock();


                    encryptedData = Encoding.UTF8.GetString(stmCipherText.ToArray());
                }
            }
            return encryptedData;
        }

        public string DecryptData(string data, string key)
        {

            byte[] encryptedMessageBytes = Encoding.UTF8.GetBytes(data);
            string decryptedData = null;
            DESCryptoServiceProvider desCryptSrvckey = new DESCryptoServiceProvider
            {
                Key = new UTF8Encoding().GetBytes(key)
            };
            desCryptSrvckey.IV = desCryptSrvckey.Key;
            using (MemoryStream encryptedStream = new MemoryStream(encryptedMessageBytes))
            {
                using (
                    CryptoStream cs = new CryptoStream(encryptedStream, desCryptSrvckey.CreateDecryptor(),
                        CryptoStreamMode.Read))
                {
                    using (StreamReader sr = new StreamReader(cs))
                    {
                        decryptedData = sr.ReadToEnd();
                    }
                }
            }
            return decryptedData;
        }

Solution

  • You declare encryptedData as a string. This is incorrect. Your encrypted data is bytes, not a character string. Attempting to convert raw bytes to UTF-8 text, as in encryptedData = Encoding.UTF8.GetString(stmCipherText.ToArray()); will not result in UTF-8 text but give you garbage and possibly lose data.

    If you want the output from your encryption to be as text, then take the cyphertext bytes and use Convert.ToBase64String() to turn them into a text string.

    When decrypting, convert the Base64 string back into bytes and decrypt the bytes.