none
The AS2 Decoder failed processing when validating the MIC

    問題

  • Hi,

    Every time we receive and AS2 message we get the following error in the windows application logs.  Does anyone know how to resolve this?

    The AS2 Decoder failed processing when validating the MIC value returned in the MDN.  Details of the MDN message are as follows:  AS2-From:"Senders AS2 ID" AS2-To:"Our AS2 ID" MessageID:"<AS2.26.BizLink.3.2.2.32.d16222b6-3153-4735-ada1-31b9f3e215f7.837bba90-a5d0-11e1-bcd4-b6f02cd89b87@b999ae157a3e19c8.5ca2c938.1377f62d959.2ba3>" OriginalMessageID:"<ServerName_5E2E6DE3-B84C-4836-80CF-07446634EBA9>"


    GilesB

    2012年5月30日 下午 05:38

解答

  • I'm assuming you are still having issues, so this is where it gets tricky.  You need to obtain the calculated MIC from BizTalk AS2 and make sure it matches the MIC calculated and returned by your partner.  If memory serves me, you should be able to track your outbound AS2 message and the MIC should be tracked.  Use a network monitor like Fiddler to monitor the response from your partner.  If for some reason, your partner is not returning a MIC in the MDN response, then they will need to configure their system to include the MIC.  If they are returning a MIC in their response, you need to determine the true value for the MIC hash.

    I also found another post that mentioned a hotfix for BizTalk Server 2006 R2.

    Post: http://social.msdn.microsoft.com/Forums/en/biztalkediandas2/thread/1c3a1c86-60d2-45f6-9166-d2b2acbc00a3

    Hotfix: http://support.microsoft.com/kb/970075/en-us

    If you need to investigate further I will include code for a simple console application that will calculate the hash for you below.

    The following link will assist in determining the message boundaries used for the MIC calculation (see page 18):

    http://www.rfc-editor.org/rfc/rfc4130.txt

    C# CODE FOR HASH GENERATION

    #region Namespaces
    // System
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    #endregion
    
    namespace CalculateMIC
    {
        class Program
        {
            #region Globals
            static bool displayUsage = false;
            static string hashingAlgorithm = "SHA1";
            static string fileName = string.Empty;
            static bool base64Encoded = false;
            static HashAlgorithm hash = new SHA1Managed();
            #endregion
    
            #region Usage Method
            /// <summary>
            /// Application Usage Information Method
            /// </summary>
            private static void Usage()
            {
                Console.WriteLine("Usage: CalculateMIC.exe [/ha [SHA1 | MD5] /f <input filename> /b64] | [/? | -?]}");
                Console.WriteLine();
                Console.WriteLine("  where:");
                Console.WriteLine();
                Console.WriteLine("     /ha [SHA1 | MD5]        - hashing algorithm either SHA1 or MD5");
                Console.WriteLine("     /f <input filename>     - filename containing the message to calculate the MIC");
                Console.WriteLine("     /b64                    - convert the hash to base64 encoding");
                Console.WriteLine("     /?                      - display usage information");
                Console.WriteLine();
                Console.WriteLine("  ex: CalculateMIC.exe /ha SHA1 /f MyAS2Message.bin /b64");
                Console.WriteLine();
                Console.WriteLine();
            }
            #endregion
    
            #region Parse Command Line
            /// <summary>
            /// Parse Command Line Parameters Method
            /// </summary>
            /// <param name="args">command line parameters</param>
            /// <returns>exception information from parsing or null (successful parse)</returns>
            private static bool ParseCommandLine(string[] args)
            {
                try
                {
                    if (args.GetLength(0) == 0)
                    {
                        displayUsage = true;
                    }
                    else
                    {
                        for (int i = 0; i < args.GetLength(0); i++)
                        {
                            switch (args[i].ToLower().Replace('-', '/'))
                            {
                                case "/ha":
                                    hashingAlgorithm = args[++i].ToUpper();
                                    break;
    
                                case "/f":
                                    fileName = args[++i];
                                    break;
    
                                case "/b64":
                                    base64Encoded = true;
                                    break;
    
                                case "/?":
                                    displayUsage = true;
                                    break;
    
                                default:
                                    throw new ApplicationException(string.Format("Invalid command argument passed: {0}", args[i]));
                            }
    
                            if (displayUsage)
                            {
                                break;
                            }
                        }
                    }
    
                    // Successful parse
                    return true;
                }
                catch (IndexOutOfRangeException)
                {
                    throw new ApplicationException("Invalid command line passed.");
                }
                catch (Exception)
                {
                    throw;
                }
            }
            #endregion
    
            #region Main Entry Point
            static void Main(string[] args)
            {
                try
                {
                    if (ParseCommandLine(args))
                    {
                        if (displayUsage)
                        {
                            // Display the usage information
                            Usage();
                        }
                        else
                        {
                            // Do the work...
                            if  (hashingAlgorithm == "MD5")
                            {
                                hash = new MD5CryptoServiceProvider();
                            }
    
                            // Hash first time
                            byte[] generatedMIC = hash.ComputeHash(File.ReadAllBytes(fileName));
    
                            if (base64Encoded)
                            {
                                Console.WriteLine("Generated MIC: {0}", Convert.ToBase64String(generatedMIC));
                            }
                            else
                            {
                                foreach (byte currentByte in generatedMIC)
                                {
                                    Console.Write("0x{0:X2} ", currentByte);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception during processing.\r\nDetails:\r\n{0}\r\n\r\n", ex.Message);
                    Usage();
                }
            }
            #endregion
        }
    }


    David Downing... If this answers your question, please Mark as the Answer. If this post is helpful, please vote as helpful.





    2012年6月6日 下午 06:02

所有回覆

  • Make sure the hashing algorithm matches.  Ask the partner if they are using Sha1 or MD5 and make sure your settings are the same.

    David Downing... If this answers your question, please Mark as the Answer. If this post is helpful, please vote as helpful.

    2012年5月30日 下午 06:56
  • Hi,

    Check the user action for this error here.


    Regards,
    Bali
    MCTS: BizTalk Server 2010,BizTalk Server 2006 and WCF
    My Blog:dpsbali-biztalkweblog
    -----------------------------------------------------
    Mark As Answer or Vote As Helpful if this helps.

    2012年5月31日 上午 05:39
  • Hi, thanks for the replys'.  We are both using Sha1

    GilesB

    2012年6月6日 下午 05:03
  • I'm assuming you are still having issues, so this is where it gets tricky.  You need to obtain the calculated MIC from BizTalk AS2 and make sure it matches the MIC calculated and returned by your partner.  If memory serves me, you should be able to track your outbound AS2 message and the MIC should be tracked.  Use a network monitor like Fiddler to monitor the response from your partner.  If for some reason, your partner is not returning a MIC in the MDN response, then they will need to configure their system to include the MIC.  If they are returning a MIC in their response, you need to determine the true value for the MIC hash.

    I also found another post that mentioned a hotfix for BizTalk Server 2006 R2.

    Post: http://social.msdn.microsoft.com/Forums/en/biztalkediandas2/thread/1c3a1c86-60d2-45f6-9166-d2b2acbc00a3

    Hotfix: http://support.microsoft.com/kb/970075/en-us

    If you need to investigate further I will include code for a simple console application that will calculate the hash for you below.

    The following link will assist in determining the message boundaries used for the MIC calculation (see page 18):

    http://www.rfc-editor.org/rfc/rfc4130.txt

    C# CODE FOR HASH GENERATION

    #region Namespaces
    // System
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    #endregion
    
    namespace CalculateMIC
    {
        class Program
        {
            #region Globals
            static bool displayUsage = false;
            static string hashingAlgorithm = "SHA1";
            static string fileName = string.Empty;
            static bool base64Encoded = false;
            static HashAlgorithm hash = new SHA1Managed();
            #endregion
    
            #region Usage Method
            /// <summary>
            /// Application Usage Information Method
            /// </summary>
            private static void Usage()
            {
                Console.WriteLine("Usage: CalculateMIC.exe [/ha [SHA1 | MD5] /f <input filename> /b64] | [/? | -?]}");
                Console.WriteLine();
                Console.WriteLine("  where:");
                Console.WriteLine();
                Console.WriteLine("     /ha [SHA1 | MD5]        - hashing algorithm either SHA1 or MD5");
                Console.WriteLine("     /f <input filename>     - filename containing the message to calculate the MIC");
                Console.WriteLine("     /b64                    - convert the hash to base64 encoding");
                Console.WriteLine("     /?                      - display usage information");
                Console.WriteLine();
                Console.WriteLine("  ex: CalculateMIC.exe /ha SHA1 /f MyAS2Message.bin /b64");
                Console.WriteLine();
                Console.WriteLine();
            }
            #endregion
    
            #region Parse Command Line
            /// <summary>
            /// Parse Command Line Parameters Method
            /// </summary>
            /// <param name="args">command line parameters</param>
            /// <returns>exception information from parsing or null (successful parse)</returns>
            private static bool ParseCommandLine(string[] args)
            {
                try
                {
                    if (args.GetLength(0) == 0)
                    {
                        displayUsage = true;
                    }
                    else
                    {
                        for (int i = 0; i < args.GetLength(0); i++)
                        {
                            switch (args[i].ToLower().Replace('-', '/'))
                            {
                                case "/ha":
                                    hashingAlgorithm = args[++i].ToUpper();
                                    break;
    
                                case "/f":
                                    fileName = args[++i];
                                    break;
    
                                case "/b64":
                                    base64Encoded = true;
                                    break;
    
                                case "/?":
                                    displayUsage = true;
                                    break;
    
                                default:
                                    throw new ApplicationException(string.Format("Invalid command argument passed: {0}", args[i]));
                            }
    
                            if (displayUsage)
                            {
                                break;
                            }
                        }
                    }
    
                    // Successful parse
                    return true;
                }
                catch (IndexOutOfRangeException)
                {
                    throw new ApplicationException("Invalid command line passed.");
                }
                catch (Exception)
                {
                    throw;
                }
            }
            #endregion
    
            #region Main Entry Point
            static void Main(string[] args)
            {
                try
                {
                    if (ParseCommandLine(args))
                    {
                        if (displayUsage)
                        {
                            // Display the usage information
                            Usage();
                        }
                        else
                        {
                            // Do the work...
                            if  (hashingAlgorithm == "MD5")
                            {
                                hash = new MD5CryptoServiceProvider();
                            }
    
                            // Hash first time
                            byte[] generatedMIC = hash.ComputeHash(File.ReadAllBytes(fileName));
    
                            if (base64Encoded)
                            {
                                Console.WriteLine("Generated MIC: {0}", Convert.ToBase64String(generatedMIC));
                            }
                            else
                            {
                                foreach (byte currentByte in generatedMIC)
                                {
                                    Console.Write("0x{0:X2} ", currentByte);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception during processing.\r\nDetails:\r\n{0}\r\n\r\n", ex.Message);
                    Usage();
                }
            }
            #endregion
        }
    }


    David Downing... If this answers your question, please Mark as the Answer. If this post is helpful, please vote as helpful.





    2012年6月6日 下午 06:02