简体   繁体   中英

How to catch a decode issue. System.FormatException: 'Invalid length for a Base-64 char array or string.'

Here is a hash encoder/decoder with a KEY feature. If I have the wrong key or partial hashed message, upon attempting to decode, I get the Bad Data error. How can I catch this before it breaks?

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string hash = "";
        public string Hash { get => hash; set => hash = value; }

        private void btnEncrypt_Click(object sender, EventArgs e)
        {
            hash = txtKey.Text;
            byte[] data = UTF8Encoding.UTF8.GetBytes(txtValue1.Text);
            using (MD5CryptoServiceProvider mDS = new MD5CryptoServiceProvider())
            {
                byte[] keys = mDS.ComputeHash(UTF8Encoding.UTF8.GetBytes(hash));
                using(TripleDESCryptoServiceProvider tripDes = new TripleDESCryptoServiceProvider() { Key = keys, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 })
                {
                    ICryptoTransform transform = tripDes.CreateEncryptor();
                    byte[] results = transform.TransformFinalBlock(data, 0, data.Length);
                    txtValue1.Text = Convert.ToBase64String(results, 0, results.Length);
                }
            }
        }

        private void btnDecrypt_Click(object sender, EventArgs e)
        {
            hash = txtKey.Text;
            byte[] data = Convert.FromBase64String(txtValue1.Text);
            using (MD5CryptoServiceProvider mDS = new MD5CryptoServiceProvider())
            {
                byte[] keys = mDS.ComputeHash(UTF8Encoding.UTF8.GetBytes(hash));
                using (TripleDESCryptoServiceProvider tripDes = new TripleDESCryptoServiceProvider() { Key = keys, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 })
                {
                    ICryptoTransform transform = tripDes.CreateDecryptor();
                    byte[] results = transform.TransformFinalBlock(data, 0, data.Length);
                    txtValue1.Text = UTF8Encoding.UTF8.GetString(results);
                }
            }
        }
    }

A Base64 string is always a multiple of 4 long. If your text in txtValue1.Text is not a multiple of 4 if(txtValue1.Text.Length % 4 != 0) then you won't be able to decode it.

Is it really base64 in that textbox? If so, have you tried appending = chars to make it a multiple of 4? ( txtValue.Text + new string('=', 4 - txtValue.Text.Length % 4) )


Detecting whether TransformFinalBlock would throw a bad data exception would require a considerable amount of code, and isn't worth doing. Just try catch it:

try{ 
  byte[] results = transform.TransformFinalBlock(data, 0, data.Length);
  txtValue1.Text = Convert.ToBase64String(results, 0, results.Length);
} catch
{
  MessageBox.Show("Key or data is incorrect");
}

If you want to catch all exceptions. If you want to catch specific exceptions, catch takes a type:

catch(FormatException)
  ...

You can have multiple type handlers at the same or parent levels in a hierarchy; specify them in "deepest or peer child to shallowest child" order

If you want to use properties of the exception use a variable name after the type so the block can access the properties of the exception

try
  ...
catch(FormatException ex)
  MessageBox "format of ..." + ex.Message
catch(SomeOtherSpecificException ex)
  ...
catch(Exception ex)
  MessageBox "general error of ..." + ex.Message

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM