none
EnvelopedCms.Encrypt() throws CryptographicException: Bad Data RRS feed

  • Question

  • I am trying to encrypt an AS2 message and EnvelopedCMS.Encrypt() throws CryptographicException: Bad Data no matter what content that I try to encrypt. The exception's ToString():

    System.Security.Cryptography.CryptographicException: Bad Data.
       at System.Security.Cryptography.Pkcs.EnvelopedCms.EncryptContent(CmsRecipientCollection recipients)
       at System.Security.Cryptography.Pkcs.EnvelopedCms.Encrypt(CmsRecipientCollection recipients)
       at System.Security.Cryptography.Pkcs.EnvelopedCms.Encrypt(CmsRecipient recipient)
       at AS2package.Encryption.Encrypt(Byte[] message, String recipientCert) in d:\AS2\Encryption.cs:line 36

    Source code for my encryption function is below. recipientCert is the filename of a .crt file that is being used for encryption.

    internal static byte[] Encrypt(byte[] message, string recipientCert)
            {
                X509Certificate2 cert = new X509Certificate2(recipientCert);
                ContentInfo contentInfo = new ContentInfo(message);
                EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo);
                CmsRecipient recipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, cert);
                envelopedCms.Encrypt(recipient);
    
                return envelopedCms.Encode();
            }

    When I use a debugger to look at the recipient object, I can see that the certificate is being loaded and has the correct information for organization, org unit, etc.

    No matter what the message content is, even if it is just a string that says "Hello", this function always throws the same Bad Data exception. The code below throws the same exception:

    String content = "Hello";
    byte[] contentBytes = Encoding.ASCII.GetBytes(content);
    contentBytes = Encrypt(contentBytes, "theirCert.crt");

    I am using .NET Framework 4.5 in Visual Studio 2012. What am I doing wrong when I try to encrypt?



    • Edited by ReksZ Thursday, August 29, 2013 7:54 PM Capitalization correction and added exception stack trace
    Thursday, August 29, 2013 7:42 PM

Answers

  • Hi ReksZ,

    > Is it possible that this exception is being thrown due to a problem with the certificate/public key? I just wish that this error message would elaborate a little more on what the problem is.

    I think you could catch more information about this issue by using MiniDump.

    public static class MiniDump

        {

            private static int mDumpError;

            private static MakeDumpArgs mArgs;

            private static MinidumpExceptionInfo mMei;

            public static bool TryDump(String dmpPath, MiniDumpType dmpType)

            {

                mArgs.path = dmpPath;

                mArgs.type = dmpType;

                mMei.ThreadId = GetCurrentThreadId();

                mMei.ExceptionPointers = Marshal.GetExceptionPointers();

                mMei.ClientPointers = false;

                Thread t = new Thread(new ThreadStart(MakeDump));

                t.Start();

                t.Join();

                return mDumpError == 0;

            }

            private static void MakeDump()

            {

                using (FileStream stream = new FileStream(mArgs.path, FileMode.Create))

                {

                    Process process = Process.GetCurrentProcess();

                    IntPtr mem = Marshal.AllocHGlobal(Marshal.SizeOf(mMei));

                    Marshal.StructureToPtr(mMei, mem, false);

                    Boolean res = MiniDumpWriteDump(

                                        process.Handle,

                                        process.Id,

                                        stream.SafeFileHandle.DangerousGetHandle(),

                                        mArgs.type,

                                        mMei.ClientPointers ? mem : IntPtr.Zero,

                                        IntPtr.Zero,

                                        IntPtr.Zero);

                    mDumpError = res ? 0 : Marshal.GetLastWin32Error();

                    Marshal.FreeHGlobal(mem);

                }

            }

            private struct MakeDumpArgs

            {

                public string path;

                public MiniDumpType type;

            }

            [DllImport("DbgHelp.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]

            private static extern Boolean MiniDumpWriteDump(

                                        IntPtr hProcess,

                                        Int32 processId,

                                        IntPtr fileHandle,

                                        MiniDumpType dumpType,

                                        IntPtr excepInfo,

                                        IntPtr userInfo,

                                        IntPtr extInfo);

            [DllImport("kernel32.dll")]

            private static extern int GetCurrentThreadId();

            [StructLayout(LayoutKind.Sequential)]

            struct MinidumpExceptionInfo

            {

                public Int32 ThreadId;

                public IntPtr ExceptionPointers;

                public bool ClientPointers;

            }

        }

        public enum MiniDumpType

        {

            Normal = 0x00000000,

            WithDataSegs = 0x00000001,

            WithFullMemory = 0x00000002,

            WithHandleData = 0x00000004,

            FilterMemory = 0x00000008,

            ScanMemory = 0x00000010,

            WithUnloadedModules = 0x00000020,

            WithIndirectlyReferencedMemory = 0x00000040,

            FilterModulePaths = 0x00000080,

            WithProcessThreadData = 0x00000100,

            WithPrivateReadWriteMemory = 0x00000200,

            WithoutOptionalData = 0x00000400,

            WithFullMemoryInfo = 0x00000800,

            WithThreadInfo = 0x00001000,

            WithCodeSegs = 0x00002000,

            WithoutAuxiliaryState = 0x00004000,

            WithFullAuxiliaryState = 0x00008000

        }

     

    > If I wanted to encrypt an AS2 message without using EnvelopedCms, what crypto class should I use to perform the same functionality?

    To help secure AS2 data transfer using encryption and digital signatures, you must have the appropriate certificates installed. See <//span>http://msdn.microsoft.com/en-us/library/bb728096.aspx for more inforamtion.

    Best Regards,


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Monday, September 9, 2013 6:05 AM
    Moderator

All replies

  • Hi ReksZ,

    This issue may be caused by Encoding. I suggest you to try this code below:

    byte[] contentBytes = Encoding.UTF8.GetBytes(content);

    See http://blogs.msdn.com/shawnfa/archive/2005/11/10/491431.aspx for more details.

    Best Regards,


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Friday, August 30, 2013 9:35 AM
    Moderator
  • Thanks for the reply, but no matter what Encoding I use, I still get this error. All of the following still throw this Bad Data exception:

    Encrypt(Encoding.Unicode.GetBytes("Hello"), "theirCert.crt");
    

    Encrypt(Encoding.UTF8.GetBytes("Hello"), "theirCert.crt");

    byte[] contentBytes = new byte[] {0x00, 0x01, 0x02, 0x03 };
    Encrypt(contentBytes, "theirCert.crt");

    Is it possible that this exception is being thrown due to a problem with the certificate/public key? I just wish that this error message would elaborate a little more on what the problem is.

    If I wanted to encrypt an AS2 message without using EnvelopedCms, what crypto class should I use to perform the same functionality?


    • Edited by ReksZ Friday, August 30, 2013 1:13 PM typo
    Friday, August 30, 2013 1:12 PM
  • Hi ReksZ,

    > Is it possible that this exception is being thrown due to a problem with the certificate/public key? I just wish that this error message would elaborate a little more on what the problem is.

    I think you could catch more information about this issue by using MiniDump.

    public static class MiniDump

        {

            private static int mDumpError;

            private static MakeDumpArgs mArgs;

            private static MinidumpExceptionInfo mMei;

            public static bool TryDump(String dmpPath, MiniDumpType dmpType)

            {

                mArgs.path = dmpPath;

                mArgs.type = dmpType;

                mMei.ThreadId = GetCurrentThreadId();

                mMei.ExceptionPointers = Marshal.GetExceptionPointers();

                mMei.ClientPointers = false;

                Thread t = new Thread(new ThreadStart(MakeDump));

                t.Start();

                t.Join();

                return mDumpError == 0;

            }

            private static void MakeDump()

            {

                using (FileStream stream = new FileStream(mArgs.path, FileMode.Create))

                {

                    Process process = Process.GetCurrentProcess();

                    IntPtr mem = Marshal.AllocHGlobal(Marshal.SizeOf(mMei));

                    Marshal.StructureToPtr(mMei, mem, false);

                    Boolean res = MiniDumpWriteDump(

                                        process.Handle,

                                        process.Id,

                                        stream.SafeFileHandle.DangerousGetHandle(),

                                        mArgs.type,

                                        mMei.ClientPointers ? mem : IntPtr.Zero,

                                        IntPtr.Zero,

                                        IntPtr.Zero);

                    mDumpError = res ? 0 : Marshal.GetLastWin32Error();

                    Marshal.FreeHGlobal(mem);

                }

            }

            private struct MakeDumpArgs

            {

                public string path;

                public MiniDumpType type;

            }

            [DllImport("DbgHelp.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]

            private static extern Boolean MiniDumpWriteDump(

                                        IntPtr hProcess,

                                        Int32 processId,

                                        IntPtr fileHandle,

                                        MiniDumpType dumpType,

                                        IntPtr excepInfo,

                                        IntPtr userInfo,

                                        IntPtr extInfo);

            [DllImport("kernel32.dll")]

            private static extern int GetCurrentThreadId();

            [StructLayout(LayoutKind.Sequential)]

            struct MinidumpExceptionInfo

            {

                public Int32 ThreadId;

                public IntPtr ExceptionPointers;

                public bool ClientPointers;

            }

        }

        public enum MiniDumpType

        {

            Normal = 0x00000000,

            WithDataSegs = 0x00000001,

            WithFullMemory = 0x00000002,

            WithHandleData = 0x00000004,

            FilterMemory = 0x00000008,

            ScanMemory = 0x00000010,

            WithUnloadedModules = 0x00000020,

            WithIndirectlyReferencedMemory = 0x00000040,

            FilterModulePaths = 0x00000080,

            WithProcessThreadData = 0x00000100,

            WithPrivateReadWriteMemory = 0x00000200,

            WithoutOptionalData = 0x00000400,

            WithFullMemoryInfo = 0x00000800,

            WithThreadInfo = 0x00001000,

            WithCodeSegs = 0x00002000,

            WithoutAuxiliaryState = 0x00004000,

            WithFullAuxiliaryState = 0x00008000

        }

     

    > If I wanted to encrypt an AS2 message without using EnvelopedCms, what crypto class should I use to perform the same functionality?

    To help secure AS2 data transfer using encryption and digital signatures, you must have the appropriate certificates installed. See <//span>http://msdn.microsoft.com/en-us/library/bb728096.aspx for more inforamtion.

    Best Regards,


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Monday, September 9, 2013 6:05 AM
    Moderator