[Mono-bugs] [Bug 77276][Wis] New - Encrypt/Decrypt generates 'Bad PKC padding' exceptions

bugzilla-daemon at bugzilla.ximian.com bugzilla-daemon at bugzilla.ximian.com
Mon Jan 16 14:06:53 EST 2006


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by wdai at fnfr.com.

http://bugzilla.ximian.com/show_bug.cgi?id=77276

--- shadow/77276	2006-01-16 14:06:53.000000000 -0500
+++ shadow/77276.tmp.12735	2006-01-16 14:06:53.000000000 -0500
@@ -0,0 +1,309 @@
+Bug#: 77276
+Product: Mono: Class Libraries
+Version: 1.1
+OS: All
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Wishlist
+Component: System.Security
+AssignedTo: sebastien at ximian.com                            
+ReportedBy: wdai at fnfr.com               
+QAContact: mono-bugs at ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Encrypt/Decrypt generates 'Bad PKC padding' exceptions
+
+Please fill in this template when reporting a bug, unless you know what 
+you are doing.
+Description of Problem:
+Encrypt/Decrypt generates error/exceptions but it works if run in .Net
+
+
+Steps to reproduce the problem:
+1.
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Security.Cryptography;
+class Program
+    {
+        private static string clearText = "any string";
+
+        static void Main(string[] args)
+        {
+            decryptError();
+            Console.ReadLine();
+            encryptTwiceError();
+            Console.ReadLine();
+        }
+
+        private static void decryptError()
+        {
+            Console.WriteLine();
+            try {
+                CryptTranslator A = new CryptTranslator();
+
+                string encrypted1 = A.Encrypt("encrypted1");
+                string encrypted2 = A.Encrypt("encrypted2");
+                string decrypted = A.Decrypt(encrypted1);
+                if ("encrypted1" == decrypted) {
+                    Console.WriteLine("A.Decrypt(encrypted1)  : " + 
+decrypted);
+                }
+                else {
+                    Console.WriteLine("Decrypted=" + decrypted);
+                }
+
+                string decrypted2 = A.Decrypt(encrypted2);
+                if ("encrypted2" == decrypted2) {
+                    Console.WriteLine("A.Decrypt(encrypted2) matches : " 
++ decrypted2);
+                }
+                else {
+                    Console.WriteLine("decrypted=" + decrypted2);
+                }
+
+                CryptTranslator B = new CryptTranslator();
+                decrypted2 = B.Decrypt(encrypted2);
+                if ("encrypted2" == decrypted2) {
+                    Console.WriteLine("B.Decrypt(encrypted2) matches : " 
++ decrypted2);
+                }
+                else {
+                    Console.WriteLine("Decrypted=" + decrypted2);
+                }
+            }
+            catch (Exception exe) {
+
+                Console.WriteLine("Decrypt Exception : " + exe.ToString
+());
+            }
+            
+        }
+        /// <summary>
+        /// can not encrypt the same string twice
+        /// </summary>
+        private static void encryptTwiceError()
+        {
+            Console.WriteLine();
+            try {
+                CryptTranslator target = new CryptTranslator();
+
+                string encrypted = target.Encrypt(clearText);
+                Console.WriteLine("encrypted 1 = " + encrypted);
+
+                encrypted = target.Encrypt(clearText);
+                Console.WriteLine("encrypted 2 = " + encrypted);
+
+                string decrypted =target.Decrypt(encrypted);
+                if (clearText == decrypted) {
+                    Console.WriteLine("Encrypt/decrypt matches : " + 
+decrypted );
+                }
+                else {
+                    Console.WriteLine("ClearText=" + clearText);
+                    Console.WriteLine("Decrypted=" + decrypted);
+                }
+            }
+            catch (Exception exe) {
+
+                Console.WriteLine("decryptWithoutFile Exception : " + 
+exe.ToString());
+            } 
+            Console.WriteLine();
+        }
+
+                   
+    } 
+
+public class CryptTranslator
+    {
+        #region private
+        private Byte[] mKeys = 
+                {117, 117, 124, 222, 134, 223, 23, 71,
+                119, 252, 198, 23, 63, 192, 178, 175,
+                146, 220, 145, 157, 174, 208, 230, 64,
+                1, 89, 207, 84, 115, 203, 61, 247};
+
+        private Byte[] mIVs =
+                {153, 116, 14, 164, 217, 5, 39, 87,
+                139, 60, 236, 145, 145, 191, 194, 153};
+
+        private ICryptoTransform mEncryptor;
+        private ICryptoTransform mDecryptor;
+        #endregion
+
+        /// <summary>
+        /// Default constructor
+        /// </summary>
+        public CryptTranslator()
+        {
+            // Init crypt variables
+            RijndaelManaged rijndael = new RijndaelManaged();
+            rijndael.GenerateKey();
+            rijndael.GenerateIV();
+            mEncryptor = rijndael.CreateEncryptor(mKeys, mIVs);
+            mDecryptor = rijndael.CreateDecryptor(mKeys, mIVs);
+        }
+
+        /// <summary>
+        /// Encrypts a string
+        /// </summary>
+        /// <param name="value">string to be encrypted</param>
+        /// <returns>encrypted string</returns>
+        public virtual string Encrypt(string value)
+        {
+
+            string retVal = String.Empty;
+
+            MemoryStream ms = new MemoryStream();
+            CryptoStream cs = new CryptoStream(ms, mEncryptor, 
+CryptoStreamMode.Write);
+
+            // Convert the data to a byte array.
+            Byte[] encryptedBytes = Encoding.ASCII.GetBytes(value);
+
+            // Write all data to the crypto stream and flush it.
+            cs.Write(encryptedBytes, 0, encryptedBytes.Length);
+            cs.FlushFinalBlock();
+            Byte[] encrypted = ms.ToArray();
+
+            // Insert commas before returning
+            if (encrypted != null)
+            {
+                for (int i = 0; i < encrypted.Length; i++)
+                {
+                    retVal += encrypted[i].ToString();
+                    if (i < encrypted.Length - 1)
+                        retVal += ",";
+                }
+            }
+            return retVal;
+        }
+
+        /// <summary>
+        /// Decrypts a string
+        /// </summary>
+        /// <param name="encryptedValue">encrypted string</param>
+        /// <returns>decrypted string</returns>
+        public virtual string Decrypt(string encryptedValue)
+        {
+
+            if (encryptedValue.Trim() == "")
+                return "";
+
+            string retVal = String.Empty;
+
+            // Strip the commas from the incoming array
+            string[] values = encryptedValue.Split(new char[] { ',' });
+            byte[] strippedBytes = new byte[values.Length];
+            bool validValue = false;
+            for (int i = 0; i < values.Length; i++)
+            {
+                strippedBytes[i] = Byte.Parse(values[i]);
+                //Console.WriteLine(strippedBytes[i].ToString());
+                validValue = true;
+            }
+
+            // If we have a valid (encrypted) value, decrypt it.
+            if (validValue)
+            {
+                MemoryStream ms = new MemoryStream();
+                CryptoStream cs = new CryptoStream(ms, mDecryptor, 
+CryptoStreamMode.Write );
+                cs.Write(strippedBytes, 0, strippedBytes.Length);
+                cs.Close();
+
+                byte[] data = ms.ToArray();
+
+                retVal = Encoding.ASCII.GetString(data);
+            }
+            return retVal;
+
+        }
+    }
+2. 
+3. 
+
+Actual Results:
+C:\svt\MonoBugs\DecryptBug\bin\Debug>mono DecryptBug.exe
+
+A.Decrypt(encrypted1)  : encrypted1
+A.Decrypt(encrypted2) matches : encrypted2
+Decrypt Exception : System.Security.Cryptography.CryptographicException: 
+Bad PKC
+S7 padding. Invalid length 157.
+in <0x000f2> 
+Mono.Security.Cryptography.SymmetricTransform:ThrowBadPaddingExcept
+ion (PaddingMode padding, Int32 length, Int32 position)
+in <0x0028f> Mono.Security.Cryptography.SymmetricTransform:FinalDecrypt 
+(System.
+Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
+in <0x00047> 
+Mono.Security.Cryptography.SymmetricTransform:TransformFinalBlock (
+System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
+in <0x00017> 
+System.Security.Cryptography.RijndaelManagedTransform:TransformFina
+lBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
+in <0x00041> System.Security.Cryptography.CryptoStream:FlushFinalBlock ()
+in <0x0001a> System.Security.Cryptography.CryptoStream:Close ()
+in <0x001e7> DecryptBug.CryptTranslator:Decrypt (System.String 
+encryptedValue)
+in <0x00184> DecryptBug.Program:decryptError ()
+
+
+encrypted 1 = 221,48,91,20,84,131,162,111,170,211,38,202,31,135,221,115
+encrypted 2 = 47,188,16,25,204,42,148,172,8,132,168,167,134,200,164,6
+decryptWithoutFile Exception : 
+System.Security.Cryptography.CryptographicExcepti
+on: Bad PKCS7 padding. Invalid length 236.
+in <0x000f2> 
+Mono.Security.Cryptography.SymmetricTransform:ThrowBadPaddingExcept
+ion (PaddingMode padding, Int32 length, Int32 position)
+in <0x0028f> Mono.Security.Cryptography.SymmetricTransform:FinalDecrypt 
+(System.
+Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
+in <0x00047> 
+Mono.Security.Cryptography.SymmetricTransform:TransformFinalBlock (
+System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
+in <0x00017> 
+System.Security.Cryptography.RijndaelManagedTransform:TransformFina
+lBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
+in <0x00041> System.Security.Cryptography.CryptoStream:FlushFinalBlock ()
+in <0x0001a> System.Security.Cryptography.CryptoStream:Close ()
+in <0x001e7> DecryptBug.CryptTranslator:Decrypt (System.String 
+encryptedValue)
+in <0x00091> DecryptBug.Program:encryptTwiceError ()
+
+
+
+
+Expected Results:
+
+A.Decrypt(encrypted1)  : encrypted1
+A.Decrypt(encrypted2) matches : encrypted2
+B.Decrypt(encrypted2) matches : encrypted2
+
+
+encrypted 1 = 221,48,91,20,84,131,162,111,170,211,38,202,31,135,221,115
+encrypted 2 = 221,48,91,20,84,131,162,111,170,211,38,202,31,135,221,115
+Encrypt/decrypt matches : any string
+
+
+
+How often does this happen? 
+Always
+
+
+Additional Information:
+First problem, decryptError routine. It seems that if you use a object to 
+encrypt multiple strings, It only works if the same object is used to 
+decrypt them. Decrypt by a new object works only when encrypt is called 
+once.
+
+Second problem, encryptTwiceError routine. If you  encrypt the same 
+string twice, decrypt no longer work.


More information about the mono-bugs mailing list