none
Problem while decryption in RSA RRS feed

  • Question

  • i am using RSA for encryption/decryption. encryption is working fyn while in decryption i m getting an error as BAD DATA....

    how to overcome it

    plz help

    Wednesday, June 13, 2012 3:00 PM

Answers

  • OK. Try this one:

    using System;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlClient;
    using System.Security.Cryptography;
    namespace Utility
    {
        public partial class DataCryptor : Form
        {
            SqlDataReader dr;
            String id = "F011DB71-8868-41cf-8F8A-CFF056AED57A";
            RSAParameters pbki, prki;
            Encoding encodingToUse = new UTF8Encoding(); 
            public DataCryptor()
            {
                InitializeComponent();
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider { KeySize = 1024 })
                {
                    pbki = rsa.ExportParameters(false);
                    prki = rsa.ExportParameters(true);
                }
            }
            private void buttonEncrypt_Click(object sender, EventArgs e)
            {
                using (SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=datacryptor;Integrated Security=True"))
                {
                    con.Open();
                    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                    {
                        rsa.ImportParameters(pbki);
                        
                        byte[] encodedTextBytes = encodingToUse.GetBytes(richTextBox1.Text);
                        byte[] encryptedBytes = rsa.Encrypt(encodedTextBytes, false);
                        string base64EncodedData = Convert.ToBase64String(encryptedBytes);
                        
                        textBoxInput.Text = base64EncodedData;
                        string query = string.Format("insert into datastorage values ('{0}','{1}')", id, base64EncodedData);
                        SqlCommand cmd = new SqlCommand(query, con);
                        cmd.ExecuteNonQuery();
                    }
                    con.Close();
                }
            }
            private void buttonDecrypt_Click(object sender, EventArgs e)
            {
                using (SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=datacryptor;Integrated Security=True"))
                {
                    con.Open();
                    string query = string.Format("select data from datastorage where id='{0}'", id);
                    SqlCommand cmd = new SqlCommand(query, con);
                    dr = cmd.ExecuteReader();
                    string base64EncodedData = null;
                    while (dr.Read()) {
                        base64EncodedData = dr["data"].ToString();
                    }
                    textBoxOutput.Text = base64EncodedData;
                    con.Close();
                    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                    {
                        rsa.ImportParameters(prki);
                        byte[] encryptedBytes = Convert.FromBase64String(base64EncodedData);
                        byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, false);
                        string decryptedString = encodingToUse.GetString(decryptedBytes);
                        richTextBoxOutput.Text = decryptedString;
                    }
                }
            }
        }
    }

    Marcel
    Thursday, June 14, 2012 6:04 PM
  • You will usually want to use symmetric algorithms to encrypt large data.
    Asymmetric algorithms like RSA are usefull only for sharing the symmetric encryption's key in a safe manner.

    Here is how you would calculate the maximum size of a cleartext that can be encrypted by RSA:

    bool fOAEP = false;
    int maxCleartextBytes = ((rsa.KeySize - rsa.LegalKeySizes[0].MinSize) / 8) + (fOAEP ? 7 : 37);
    
    if (encodedTextBytes.Length > maxCleartextBytes) {
        rsa.Clear();
        throw (new InvalidOperationException(String.Format("Cannot encrypt more than {0} bytes!", maxCleartextBytes)));
    }
    
    byte[] encryptedBytes = rsa.Encrypt(encodedTextBytes, fOAEP);
    


    You might be tempted to divide your cleartext into blocks and encrypt each of them using the same key. Don't. Take instead a good symmetric algorithm, like AesCryptoServiceProvider, and do the encryption of your data with it. This is much more efficient and safe. Then encrypt the key with the recipient's public key using e.g. RSA to safely transmit it over the wire.

    Marcel

    Thursday, June 14, 2012 9:14 PM
  • The MSDN documentation has a quite self-explanatory example on how to use the AesCryptoServiceProvider class to encrypt and decrypt data. Maybe you will want to take a closer look?

    Now to your code. There are several issues, here the main ones:

    1. AES has a fixed block size of 16 byte. So even if your plaintext byte array is 11 bytes long as in your example, the output of the encryption will still hold 16 bytes. So, just instantiate MemoryStream without any length parameters and you're done.

    2. You forgot to *close* the StreamWriter instance before returning the MemoryStream's buffer. If you don't call sw.Close(), the crypto stream will never entirely get flushed back to the memory stream which will remain empty.


    using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace AES { class Program { static void Main(string[] args) { System.Text.UTF8Encoding utf = new UTF8Encoding(); Console.WriteLine("AES Encryption"); string text = "How are you"; Console.WriteLine("Original text:\n\n" + text); byte[] txt = utf.GetBytes(text); AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); byte[] key = aes.Key; byte[] iv = aes.IV; ICryptoTransform ict = aes.CreateEncryptor(key, iv); MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, ict, CryptoStreamMode.Write); StreamWriter sw = new StreamWriter(cs); sw.Write(text); sw.Close(); // flush decrypted bytes to MemoryStream byte[] en = ms.ToArray();

    // Not needed as sw.Close() flushes the bytes to the CryptoStream
    // and then calls cs.Close(). When this happens CryptoStream flushes
    // the decrypted bytes to the MemoryStream. Then it calls ms.Close() //cs.Close(); //ms.Close();

    // Not needed as Close() will call Dispose(true) //sw.Dispose(); //cs.Dispose(); //ms.Dispose(); Console.WriteLine("\nCrypted Text:\n\n," + Convert.ToBase64String(en)); ICryptoTransform dct = aes.CreateDecryptor(key, iv);
    // Here we can specify a buffer, because we only read
    // from the stream and don't need to grow it. MemoryStream dms = new MemoryStream(en); CryptoStream dcs = new CryptoStream(dms, dct, CryptoStreamMode.Read); StreamReader sr = new StreamReader(dcs); string decryptedText = sr.ReadToEnd(); Console.WriteLine("\nDeCrypted Text:\n\n" + decryptedText); sr.Close(); // also closes the underlying stream

    // Clean-up aes.Clear(); aes.Dispose(); Array.Clear(key, 0, key.Length); Array.Clear(iv, 0, iv.Length); Console.ReadKey(true); } } }

    Hope this helps.

    Marcel

    Saturday, June 16, 2012 12:00 AM

All replies

  • First, you don't know if your encryption is working properly until you can decrypt the message.  Just because the code runs without errors doesn't mean the encryption is working properly.  You error indicates that either the encryption is wrong, the decryption is wrong, or both the encryption and decryption is wrong.

    See sample code on this webpage to see if it helps solve your issues

    http://msdn.microsoft.com/en-us/library/system.security.cryptography.asymmetricalgorithm


    jdweng

    Wednesday, June 13, 2012 4:42 PM
  • Hi,

    This could really have a lot of causes, ranging from character encoding issues to bad key management. Without seeing any code it's hard to tell. If you want to do the diagnosis on your own, I would suggest you to extract the encryption/decryption code from your project and paste it to a newly created .NET 3.5 project. Then go download System.Cryptography.Debug.dll from CodePlex, read the accompanying documentation, and use it in your project to get more meaningful messages. You also will want to verify your decryption code against the available RSACryptoServiceProvider.Decrypt-sample for a start.

    Marcel

    Wednesday, June 13, 2012 5:23 PM
  • Marcel: Since  Rumman is using the Net Library which we know performs the encrypt/cecript algorithms correctly, I don't think it is very useful to go to another software package.  I would say  Martcel are correct if Rumman was developing his own code for performing the encrypt/decrypt alogrithms.

    The best way of finding the problem is comparing known work code in the link I provided against Marcel code.

    Normally the best way of solving these problems is first to eliminate the public key algorithm and use a fix key.  Also start with a short test message of less than 20 character.  See if you always get the same encrypted message every time.  Then see if you alway get the same decrypted message everytime (it may not match the transmitted message but it is useful aid in debugging to find out the receive message is always the same).


    jdweng

    Wednesday, June 13, 2012 7:04 PM
  • Hi, 

    If you provide code part what you are using to decrypt will be useful for us to solve.

    One of the reason I can think, from while solving this issue, of BAD DATA error on decrypt, passing wrong inputCount to TransformFinalBlock call.


    If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".


    • Edited by Kris444 Wednesday, June 13, 2012 7:23 PM
    Wednesday, June 13, 2012 7:23 PM
  • on same program level its working fine... but when i m going for databases it is giving an error.

    RSACryptoServiceProvider rsa=new RSACryptoServiceProvider();

    ASCIIEncoding ascii=new ASCIIEncoding();

    byte[] text=ascii.GetBytes(original string);

    text=rsa.Encrypt(text,false);

    string str = ascii.GetString(text);

    to store the encrypted text in database i have to convert the byte[] generated through rsa.encrypt() method to string.

    now when i retrieve it back it will give me back as string which i stored i.e. the encrypted string...

    now what i am doing is:

    byte[] data = ascii.GetBytes(encrypted string);  /* which i retrieve from database, which is "str" in this case */

    data = rsa.Decrypt(data,false);

    now at this bold line i am getting bad data error !!

    Wednesday, June 13, 2012 8:13 PM
  • You can't use ascii encoding on a database which is binary.  I recommend that you use UUENCODE and UUDECODE to convert the database to ascii before you encrypt/decrypt.

    jdweng

    Wednesday, June 13, 2012 9:27 PM
  • Even when if i use unicode encoding its still giving same error !!
    Wednesday, June 13, 2012 9:51 PM
  • Rumman,

    As I suspected from the start, you are making a very common mistake: You are roundtripping cipher text via encoding. Please read Shawn Farkas article on the subject. In brief: Ascii encoding uses only 7 of the 8 available bits, which means that you are loosing a bit on every encrypted byte that you encode to a string. This results in ... bad data. What to do? Use Convert.ToBase64String(encryptedBytes) to get the string you need to store to the database, and when reading it back again use Convert.FromBase64String(base64String) to get your encrypted bytes again. Have fun.

    Marcel

    Wednesday, June 13, 2012 9:54 PM
  • Maybe it's a little bit to abstract to understand? - All right, I extended the MSDN-sample to display the encoded bits of each encryption byte. Now, take a look at the output.

    Every time the 8th bit of a encrypted byte is set, the encoding fails because value is out of the ASCII encoding range. When it fails, it replaces the char with a so called 'replacement char' (in our case a question mark with the binary value of 00111111). Here is the code.

    using System;
    using System.Text;
    using System.Security.Cryptography;
    namespace EncodingRoundtripMistake
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    //Create a UnicodeEncoder to convert between byte array and string.
                    ASCIIEncoding encodingToUse = new ASCIIEncoding();
                    
                    //Will result in CryptographicException if uncommented
                    //UTF8Encoding encodingToUse = new UTF8Encoding();
                    string dataString = "Data to Encrypt";
                    //Create byte arrays to hold original, encrypted, and decrypted data.
                    byte[] dataToEncrypt = encodingToUse.GetBytes(dataString);
                    byte[] encryptedData_Good;
                    byte[] decryptedData;
                    //Create a new instance of the RSACryptoServiceProvider class 
                    // and automatically create a new key-pair.
                    using (RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider())
                    {
                        //Display the origianl data to the console.
                        Console.WriteLine("Original Data: {0}", dataString);
                        //Encrypt the byte array and specify no OAEP padding.  
                        //OAEP padding is only available on Microsoft Windows XP or
                        //later.  
                        encryptedData_Good = RSAalg.Encrypt(dataToEncrypt, false);
                        // We deliberately make the mistake of using encoding to
                        // transform the encrypted bytes to text. For why this is incorrect
                        // refer to: http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx
                        var encryptedString_Wrong = encodingToUse.GetString(encryptedData_Good);
                        // This is how you should convert a byte array to a string
                        var encryptedString_Good = Convert.ToBase64String(encryptedData_Good);
                        // Now we try to transform the ecrypted string back to a byte array
                        byte[] encryptedData_Wrong = encodingToUse.GetBytes(encryptedString_Wrong);
                        
                        // We'll now compare the two byte arrays
                        if (encryptedData_Good.Length == encryptedData_Wrong.Length)
                            for (int i = 0; i < encryptedData_Good.Length; i++)
                            {
                                string expected = Convert.ToString(encryptedData_Good[i], 2).PadLeft(8, '0');
                                string current = Convert.ToString(encryptedData_Wrong[i], 2).PadLeft(8, '0');
                                if (encryptedData_Wrong[i] != encryptedData_Good[i])
                                    Console.WriteLine("Byte {0}\nExpected:\t{1} (0x{2:X}, 8th bit is set)\nCurrent :\t{3} (0x{4:X}, -> replacement char '?')\n", i, expected, encryptedData_Good[i], current, encryptedData_Wrong[i]);
                                else
                                    Console.WriteLine("Byte {0}\nExpected:\t{1} (0x{2:X})\nCurrent :\t{3} (0x{4:X})\n", i, expected, encryptedData_Good[i], current, encryptedData_Wrong[i]);
                            }
                        else
                            Console.WriteLine("Error: The two encrypted byte arrays have different lengths!");
                        //Pass the data to ENCRYPT and boolean flag specifying 
                        //no OAEP padding.
                        decryptedData = RSAalg.Decrypt(encryptedData_Good, false);
                        //Display the decrypted plaintext to the console. 
                        Console.WriteLine("1. Decrypted plaintext: {0}", encodingToUse.GetString(decryptedData));
                        // This is how you should convert a byte array to a string
                        encryptedData_Good = Convert.FromBase64String(encryptedString_Good);
                        decryptedData = RSAalg.Decrypt(encryptedData_Good, false);
                        Console.WriteLine("2. Decrypted plaintext: {0}", encodingToUse.GetString(decryptedData));
                        // Will result in CryptographicException: Bad data.
                        decryptedData = RSAalg.Decrypt(encryptedData_Wrong, false);
                        Console.WriteLine("3. Decrypted plaintext: {0}", encodingToUse.GetString(decryptedData));
                    }
                }
                catch (CryptographicException e)
                {
                    //Catch this exception in case the encryption did
                    //not succeed.
                    Console.WriteLine("{0}:{1}", e.GetType(), e.Message);
                }
                Console.ReadKey(true);
            }
        }
    }

    Marcel
    Thursday, June 14, 2012 12:40 PM
  • byte[] dataToEncrypt = encodingToUse.GetBytes(dataString);

    is this line correct ?? since in this line you have used 'encodingToUse' which is an ASCIIEncoding object

    moreover i have used this code but still i am getting BAD DATA error...!!

    Thursday, June 14, 2012 3:05 PM
  • > Is this line correct?
    Well, depends on what you are encrypting. If you need another encoding, like UTF8, go ahead and use UTF8Encoding. I cannot guess what exactly you are encrypting. For plain english text like "Data to encrypt" ASCIIEncoding should be sufficient.

    > I have used this code but still I am getting BAD DATA error!
    Which "code" eactly are you using? - The decryption of encryptedData_Wrong will allways fail, because it contains bad data. I put it there for you to observe what you shouldn't do.

    Can you post a complete piece of code that reproduces the problem (and prooves that you understood what I was writing)? Please also include the cleartext.

    Marcel


    Thursday, June 14, 2012 3:22 PM
  • using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlClient;
    using System.Security.Cryptography;

    namespace Utility
    {
        public partial class DataCryptor : Form
        {
            SqlConnection con;
            SqlCommand cmd;
            SqlDataReader dr;

            RSAParameters pbki, prki;

            ASCIIEncoding ascii = new ASCIIEncoding();

            public DataCryptor()
            {
                InitializeComponent();

                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.KeySize = 1024;

                pbki = rsa.ExportParameters(false);
                prki = rsa.ExportParameters(true);
            }

            private void button2_Click(object sender, EventArgs e)
            {
                con = new SqlConnection(@"Data Source=WINXP-324C56\SQLEXPRESS;Initial Catalog=datacryptor;Integrated Security=True");
                con.Open();

           /*     MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                byte[] id = Encoding.ASCII.GetBytes(textBox1.Text);
                id = md5.ComputeHash(id);
                string str = Encoding.ASCII.GetString(id);  */

                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.ImportParameters(pbki);
                byte[] text = ascii.GetBytes(richTextBox1.Text);
                text = rsa.Encrypt(text, false);
                string data = Convert.ToBase64String(text);

                string query = string.Format("insert into datastorage values ('{0}','{1}')", str, data);
                cmd = new SqlCommand(query,con);

                cmd.ExecuteNonQuery();

                MessageBox.Show("Crypted", "Success");
            }

            private void button3_Click(object sender, EventArgs e)
            {
                Random r = new Random();
                textBox1.Text = r.Next().ToString();
            }

            private void button4_Click(object sender, EventArgs e)
            {
                con = new SqlConnection(@"Data Source=WINXP-324C56\SQLEXPRESS;Initial Catalog=datacryptor;Integrated Security=True");
                con.Open();

            /*    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                byte[] id = Encoding.ASCII.GetBytes(textBox2.Text);
                id = md5.ComputeHash(id);
                string str = Encoding.ASCII.GetString(id);   */

                string query = string.Format("select data from datastorage where id='{0}'", str);
                cmd = new SqlCommand(query, con);

                dr = cmd.ExecuteReader();

                string data=null;
                while (dr.Read())
                {
                    data = dr["data"].ToString();
                }

                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.ImportParameters(prki);
                byte[] text = Convert.FromBase64String(data);
                text = rsa.Decrypt(text, false);

                richTextBox2.Text = Convert.ToBase64String(text);
            }
        }
    }

    In this code i am not getting BAD DATA error but the code is not decrypting correctly...!!

    and really thanks a lot for your support


    • Edited by Rumman Siddiqui Thursday, June 14, 2012 3:55 PM comment included
    Thursday, June 14, 2012 3:46 PM
  • OK. Try this one:

    using System;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlClient;
    using System.Security.Cryptography;
    namespace Utility
    {
        public partial class DataCryptor : Form
        {
            SqlDataReader dr;
            String id = "F011DB71-8868-41cf-8F8A-CFF056AED57A";
            RSAParameters pbki, prki;
            Encoding encodingToUse = new UTF8Encoding(); 
            public DataCryptor()
            {
                InitializeComponent();
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider { KeySize = 1024 })
                {
                    pbki = rsa.ExportParameters(false);
                    prki = rsa.ExportParameters(true);
                }
            }
            private void buttonEncrypt_Click(object sender, EventArgs e)
            {
                using (SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=datacryptor;Integrated Security=True"))
                {
                    con.Open();
                    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                    {
                        rsa.ImportParameters(pbki);
                        
                        byte[] encodedTextBytes = encodingToUse.GetBytes(richTextBox1.Text);
                        byte[] encryptedBytes = rsa.Encrypt(encodedTextBytes, false);
                        string base64EncodedData = Convert.ToBase64String(encryptedBytes);
                        
                        textBoxInput.Text = base64EncodedData;
                        string query = string.Format("insert into datastorage values ('{0}','{1}')", id, base64EncodedData);
                        SqlCommand cmd = new SqlCommand(query, con);
                        cmd.ExecuteNonQuery();
                    }
                    con.Close();
                }
            }
            private void buttonDecrypt_Click(object sender, EventArgs e)
            {
                using (SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=datacryptor;Integrated Security=True"))
                {
                    con.Open();
                    string query = string.Format("select data from datastorage where id='{0}'", id);
                    SqlCommand cmd = new SqlCommand(query, con);
                    dr = cmd.ExecuteReader();
                    string base64EncodedData = null;
                    while (dr.Read()) {
                        base64EncodedData = dr["data"].ToString();
                    }
                    textBoxOutput.Text = base64EncodedData;
                    con.Close();
                    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                    {
                        rsa.ImportParameters(prki);
                        byte[] encryptedBytes = Convert.FromBase64String(base64EncodedData);
                        byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, false);
                        string decryptedString = encodingToUse.GetString(decryptedBytes);
                        richTextBoxOutput.Text = decryptedString;
                    }
                }
            }
        }
    }

    Marcel
    Thursday, June 14, 2012 6:04 PM
  • Thanks a lot...

    finally you gave me solution. Its working perfectly fine. but for large data its giving error at:

    byte[] encryptedBytes = rsa.Encrypt(encodedTextBytes, false);

    as Key not valid for use in specified state. is it due to the keysize property ?

    Any suggestion how to remove this exception ?

    Thursday, June 14, 2012 8:10 PM
  • You will usually want to use symmetric algorithms to encrypt large data.
    Asymmetric algorithms like RSA are usefull only for sharing the symmetric encryption's key in a safe manner.

    Here is how you would calculate the maximum size of a cleartext that can be encrypted by RSA:

    bool fOAEP = false;
    int maxCleartextBytes = ((rsa.KeySize - rsa.LegalKeySizes[0].MinSize) / 8) + (fOAEP ? 7 : 37);
    
    if (encodedTextBytes.Length > maxCleartextBytes) {
        rsa.Clear();
        throw (new InvalidOperationException(String.Format("Cannot encrypt more than {0} bytes!", maxCleartextBytes)));
    }
    
    byte[] encryptedBytes = rsa.Encrypt(encodedTextBytes, fOAEP);
    


    You might be tempted to divide your cleartext into blocks and encrypt each of them using the same key. Don't. Take instead a good symmetric algorithm, like AesCryptoServiceProvider, and do the encryption of your data with it. This is much more efficient and safe. Then encrypt the key with the recipient's public key using e.g. RSA to safely transmit it over the wire.

    Marcel

    Thursday, June 14, 2012 9:14 PM
  • While using AesCryptoServiceProvider

    in this code as:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    using System.IO;

    namespace AES
    {
        class Program
        {
            static void Main(string[] args)
            {
                System.Text.UTF8Encoding utf=new UTF8Encoding();

                Console.WriteLine("AES Encryption");

                string text="How are you";
                byte[] txt = utf.GetBytes(text);
                Console.WriteLine("Original text: " + text);

                AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
                byte[] key = aes.Key;
                byte[] iv = aes.IV;

                ICryptoTransform ict = aes.CreateEncryptor(key, iv);

                MemoryStream ms = new MemoryStream(txt,0,txt.Length);

                CryptoStream cs = new CryptoStream(ms, ict, CryptoStreamMode.Write);

                StreamWriter sw = new StreamWriter(cs);
                sw.Write(text);

                byte[] en = ms.ToArray();
                ms.Close();

                Console.WriteLine("Crypted Text: " + Convert.ToBase64String(en));

                ICryptoTransform dct = aes.CreateDecryptor(key, iv);

                MemoryStream dms = new MemoryStream(en,0,en.Length);

                CryptoStream dcs = new CryptoStream(dms, dct, CryptoStreamMode.Read);

                StreamReader sr = new StreamReader(dcs);

                Console.WriteLine("DeCrypted Text: " + sr.ReadToEnd());
                dms.Close();

                Console.Read();
            }
        }
    }

    i am getting an error as The input data is not a complete blockat bold line.

    i searched over internet but is not able to rectify it !!

    what could be the possible error now in my code ??

    Friday, June 15, 2012 9:31 PM
  • The MSDN documentation has a quite self-explanatory example on how to use the AesCryptoServiceProvider class to encrypt and decrypt data. Maybe you will want to take a closer look?

    Now to your code. There are several issues, here the main ones:

    1. AES has a fixed block size of 16 byte. So even if your plaintext byte array is 11 bytes long as in your example, the output of the encryption will still hold 16 bytes. So, just instantiate MemoryStream without any length parameters and you're done.

    2. You forgot to *close* the StreamWriter instance before returning the MemoryStream's buffer. If you don't call sw.Close(), the crypto stream will never entirely get flushed back to the memory stream which will remain empty.


    using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace AES { class Program { static void Main(string[] args) { System.Text.UTF8Encoding utf = new UTF8Encoding(); Console.WriteLine("AES Encryption"); string text = "How are you"; Console.WriteLine("Original text:\n\n" + text); byte[] txt = utf.GetBytes(text); AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); byte[] key = aes.Key; byte[] iv = aes.IV; ICryptoTransform ict = aes.CreateEncryptor(key, iv); MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, ict, CryptoStreamMode.Write); StreamWriter sw = new StreamWriter(cs); sw.Write(text); sw.Close(); // flush decrypted bytes to MemoryStream byte[] en = ms.ToArray();

    // Not needed as sw.Close() flushes the bytes to the CryptoStream
    // and then calls cs.Close(). When this happens CryptoStream flushes
    // the decrypted bytes to the MemoryStream. Then it calls ms.Close() //cs.Close(); //ms.Close();

    // Not needed as Close() will call Dispose(true) //sw.Dispose(); //cs.Dispose(); //ms.Dispose(); Console.WriteLine("\nCrypted Text:\n\n," + Convert.ToBase64String(en)); ICryptoTransform dct = aes.CreateDecryptor(key, iv);
    // Here we can specify a buffer, because we only read
    // from the stream and don't need to grow it. MemoryStream dms = new MemoryStream(en); CryptoStream dcs = new CryptoStream(dms, dct, CryptoStreamMode.Read); StreamReader sr = new StreamReader(dcs); string decryptedText = sr.ReadToEnd(); Console.WriteLine("\nDeCrypted Text:\n\n" + decryptedText); sr.Close(); // also closes the underlying stream

    // Clean-up aes.Clear(); aes.Dispose(); Array.Clear(key, 0, key.Length); Array.Clear(iv, 0, iv.Length); Console.ReadKey(true); } } }

    Hope this helps.

    Marcel

    Saturday, June 16, 2012 12:00 AM
  • Thanks a lot again.

    this worked well

    Saturday, June 16, 2012 9:00 AM