title: CryptographicException: Bad PKCS7 padding
body: <p>I am seeing a small percentage of production users randomly report this exception related to encrypting/decrypting strings with Xamarin.Android but unfortunately I cannot reproduce it.</p>
  
  <p>What could cause this and/or how could I reproduce the exception so that I can figure out a fix/workaround?</p>
  
  <pre><code>[CryptographicException: Bad PKCS7 padding. Invalid length 147.]
      Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException(PaddingMode padding, Int32 length, Int32 position):0
      Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt(System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount):0
      Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock(System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount):0
      System.Security.Cryptography.CryptoStream.FlushFinalBlock():0
      com.abc.mobile.shared.Security+PasswordEncoder.DecryptWithByteArray(System.String strText, System.String strEncrypt):0
  </code></pre>
  
  <p>EDIT: Here's the code I am using to encrypt/decrypt</p>
  
  <pre><code>    private string EncryptWithByteArray(string inPassword, string inByteArray)
      {
  
          byte[] tmpKey = new byte[20];
          tmpKey = System.Text.Encoding.UTF8.GetBytes(inByteArray.Substring(0, 8));
          DESCryptoServiceProvider des = new DESCryptoServiceProvider();
          byte[] inputArray = System.Text.Encoding.UTF8.GetBytes(inPassword);
          MemoryStream ms = new MemoryStream();
          CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(tmpKey, mInitializationVector), CryptoStreamMode.Write);
          cs.Write(inputArray, 0, inputArray.Length);
          cs.FlushFinalBlock();
          return Convert.ToBase64String(ms.ToArray());
  
      }
  
          private string DecryptWithByteArray (string strText, string strEncrypt)
          {
  
              try
              {
                  byte[] tmpKey = new byte[20];
                  tmpKey = System.Text.Encoding.UTF8.GetBytes (strEncrypt.Substring (0, 8));
                  DESCryptoServiceProvider des = new DESCryptoServiceProvider ();
                  Byte[] inputByteArray = Convert.FromBase64String (strText);
                  MemoryStream ms = new MemoryStream ();
                  CryptoStream cs = new CryptoStream (ms, des.CreateDecryptor (tmpKey, mInitializationVector), CryptoStreamMode.Write);
                  cs.Write (inputByteArray, 0, inputByteArray.Length);
              try {
                  cs.FlushFinalBlock();
              } catch (Exception ex) {
                  throw(ex);
              }
              System.Text.Encoding encoding = System.Text.Encoding.UTF8;
              return encoding.GetString(ms.ToArray());
              }
              catch (Exception ex)
              {
                  throw ex;
              }
          }
  </code></pre>
  
  <p>EDIT 2: </p>
  
  <p>The encryption key is always the local Device ID. Here's how I am getting this:</p>
  
  <pre><code>        TelephonyManager telephonyMgr = Application.Context.GetSystemService(Context.TelephonyService) as TelephonyManager;
          string deviceId = telephonyMgr.DeviceId == null ? "UNAVAILABLE" : telephonyMgr.DeviceId;
  </code></pre>
  
  <p>Here's an example of how it's called:</p>
  
  <pre><code>string mByteArray = GetDeviceId();
  string mEncryptedString = EncryptWithByteArray(stringToEncrypt, mByteArray);
  string mDecryptedString = DecryptWithByteArray(mEncryptedString, mByteArray);
  </code></pre>