private static Interop.Crypt32.CertNameStrTypeAndFlags MapNameToStrFlag(X500DistinguishedNameFlags flag)
        {
            // All values or'ed together. Change this if you add values to the enumeration.
            uint allFlags = 0x71F1;
            uint dwFlags = (uint)flag;
            Debug.Assert((dwFlags & ~allFlags) == 0);

            Interop.Crypt32.CertNameStrTypeAndFlags dwStrType = 0;
            if (dwFlags != 0)
            {
                if ((flag & X500DistinguishedNameFlags.Reversed) == X500DistinguishedNameFlags.Reversed)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_REVERSE_FLAG;

                if ((flag & X500DistinguishedNameFlags.UseSemicolons) == X500DistinguishedNameFlags.UseSemicolons)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_SEMICOLON_FLAG;
                else if ((flag & X500DistinguishedNameFlags.UseCommas) == X500DistinguishedNameFlags.UseCommas)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_COMMA_FLAG;
                else if ((flag & X500DistinguishedNameFlags.UseNewLines) == X500DistinguishedNameFlags.UseNewLines)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_CRLF_FLAG;

                if ((flag & X500DistinguishedNameFlags.DoNotUsePlusSign) == X500DistinguishedNameFlags.DoNotUsePlusSign)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_NO_PLUS_FLAG;
                if ((flag & X500DistinguishedNameFlags.DoNotUseQuotes) == X500DistinguishedNameFlags.DoNotUseQuotes)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_NO_QUOTING_FLAG;

                if ((flag & X500DistinguishedNameFlags.ForceUTF8Encoding) == X500DistinguishedNameFlags.ForceUTF8Encoding)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG;

                if ((flag & X500DistinguishedNameFlags.UseUTF8Encoding) == X500DistinguishedNameFlags.UseUTF8Encoding)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG;
                else if ((flag & X500DistinguishedNameFlags.UseT61Encoding) == X500DistinguishedNameFlags.UseT61Encoding)
                    dwStrType |= Interop.Crypt32.CertNameStrTypeAndFlags.CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
            }
            return dwStrType;
        }
        public byte[] X500DistinguishedNameEncode(string distinguishedName, X500DistinguishedNameFlags flag)
        {
            Debug.Assert(distinguishedName != null);

            Interop.Crypt32.CertNameStrTypeAndFlags dwStrType = Interop.Crypt32.CertNameStrTypeAndFlags.CERT_X500_NAME_STR | MapNameToStrFlag(flag);

            int cbEncoded = 0;
            if (!Interop.Crypt32.CertStrToName(Interop.Crypt32.CertEncodingType.All, distinguishedName, dwStrType, IntPtr.Zero, null, ref cbEncoded, IntPtr.Zero))
                throw Marshal.GetLastWin32Error().ToCryptographicException();

            byte[] encodedName = new byte[cbEncoded];
            if (!Interop.Crypt32.CertStrToName(Interop.Crypt32.CertEncodingType.All, distinguishedName, dwStrType, IntPtr.Zero, encodedName, ref cbEncoded, IntPtr.Zero))
                throw Marshal.GetLastWin32Error().ToCryptographicException();

            return encodedName;
        }