C# CertCreateSelfSignCertificate返回null,错误代码87

C# CertCreateSelfSignCertificate返回null,错误代码87,c#,cryptography,pinvoke,C#,Cryptography,Pinvoke,我在C#中使用crypt api创建SSL证书时遇到问题,CertCreateSelfSignCertificate返回null,错误代码87(参数不正确)。 不知道错过了什么 Win32Native.CRYPTOAPI_BLOB SubjectIssuerBlob = new Win32Native.CRYPTOAPI_BLOB(); GCHandle asnNameHandle = GCHandle.Alloc(pbEncoded, GCHandleType.

我在C#中使用crypt api创建SSL证书时遇到问题,CertCreateSelfSignCertificate返回null,错误代码87(参数不正确)。 不知道错过了什么

Win32Native.CRYPTOAPI_BLOB SubjectIssuerBlob = new Win32Native.CRYPTOAPI_BLOB();
                GCHandle asnNameHandle = GCHandle.Alloc(pbEncoded, GCHandleType.Pinned);
                // SubjectIssuerBlob.pbData = Marshal.AllocHGlobal(pbEncoded.Length);
                //Marshal.Copy(pbEncoded, 0, SubjectIssuerBlob.pbData, pbEncoded.Length);
                SubjectIssuerBlob.pbData = asnNameHandle.AddrOfPinnedObject();
                SubjectIssuerBlob.cbData = cbEncoded;

Win32Native.CRYPT_KEY_PROV_INFO providerInfo = new Win32Native.CRYPT_KEY_PROV_INFO();
                providerInfo.pwszContainerName = hostname;
                providerInfo.pwszProvName = null;
                providerInfo.dwProvType = PROV_RSA_FULL;
                providerInfo.dwFlags = CRYPT_MACHINE_KEYSET;
                providerInfo.cProvParam = 0;
                providerInfo.rgProvParam = IntPtr.Zero;
                providerInfo.dwKeySpec = AT_SIGNATURE;

                Win32Native.CRYPT_ALGORITHM_IDENTIFIER algorithmID = new Win32Native.CRYPT_ALGORITHM_IDENTIFIER();
                algorithmID.pszObjId = "1.2.840.113549.1.1.5"; //szOID_RSA_SHA1RSA

pContext = Win32Native.CertCreateSelfSignCertificate(IntPtr.Zero, ref SubjectIssuerBlob, 0, ref providerInfo, ref algorithmID, null, endtime, IntPtr.Zero);
win32api调用

[DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
        internal static extern IntPtr CertCreateSelfSignCertificate(
           IntPtr providerHandle,
           ref CRYPTOAPI_BLOB subjectIssuerBlob,
           uint flags,
           ref CRYPT_KEY_PROV_INFO pKeyProvInfo,
           ref CRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
           SystemTime startTime,
           SystemTime endTime,
           IntPtr extensions);

在Windows 10上使用CertCreateSelfSignCertificate进行测试,与2015年相比=>

对话框(法语):

带声明=>

    [DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern IntPtr CertCreateSelfSignCertificate(IntPtr hCryptProvOrNCryptKey, ref CERT_NAME_BLOB pSubjectIssuerBlob, int dwFlags, ref CRYPT_KEY_PROV_INFO pKeyProvInfo,
        IntPtr pSignatureAlgorithm, IntPtr pStartTime, IntPtr pEndTime, IntPtr pExtensions);

    [DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CertFreeCertificateContext(IntPtr pCertContext);

    [StructLayout(LayoutKind.Sequential)]
    public struct CERT_NAME_BLOB
    {
        public int cbData;
        public IntPtr pbData;
    }

    [DllImport("Rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern int UuidCreate(out Guid Uuid);

    [DllImport("rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern int UuidToString(ref Guid uuid, ref IntPtr str);

    [DllImport("rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern int RpcStringFree(ref IntPtr str);

    [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CryptAcquireContext(ref IntPtr phProv, string szContainer, string szProvider, int dwProvType, uint dwFlags);

    [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);

    [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CryptGenKey(IntPtr hProv, uint Algid, int dwFlags, ref IntPtr phKey);

    [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CryptDestroyKey(IntPtr hKey);

    public const int RSA1024BIT_KEY = 0x04000000;
    public const int CRYPT_EXPORTABLE = 0x00000001;

    [DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CertStrToName(uint dwCertEncodingType, string pszX500, uint dwStrType, IntPtr pvReserved,
        [In, Out] byte[] pbEncoded, ref uint pcbEncoded, IntPtr ppszError);

    public const int CRYPT_ASN_ENCODING = 0x00000001;
    public const int CRYPT_NDR_ENCODING = 0x00000002;
    public const int X509_ASN_ENCODING = 0x00000001;
    public const int X509_NDR_ENCODING = 0x00000002;
    public const int PKCS_7_ASN_ENCODING = 0x00010000;
    public const int PKCS_7_NDR_ENCODING = 0x00020000;

    public const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";
    public const int PROV_RSA_FULL = 1;

    public const uint CRYPT_VERIFYCONTEXT = 0xF0000000;
    public const uint CRYPT_NEWKEYSET = 0x00000008;
    public const uint CRYPT_DELETEKEYSET = 0x00000010;
    public const uint CRYPT_MACHINE_KEYSET = 0x00000020;
    public const uint CRYPT_SILENT = 0x00000040;

    public const int CERT_SIMPLE_NAME_STR = 1;
    public const int CERT_OID_NAME_STR = 2;
    public const int CERT_X500_NAME_STR = 3;
    public const int CERT_XML_NAME_STR = 4;

    public const int CERT_NAME_STR_SEMICOLON_FLAG = 0x40000000;
    public const int CERT_NAME_STR_NO_PLUS_FLAG = 0x20000000;
    public const int CERT_NAME_STR_NO_QUOTING_FLAG = 0x10000000;
    public const int CERT_NAME_STR_CRLF_FLAG = 0x08000000;
    public const int CERT_NAME_STR_COMMA_FLAG = 0x04000000;
    public const int CERT_NAME_STR_REVERSE_FLAG = 0x02000000;
    public const int CERT_NAME_STR_FORWARD_FLAG = 0x01000000;

    public const int CERT_NAME_STR_DISABLE_IE4_UTF8_FLAG = 0x00010000;
    public const int CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG = 0x00020000;
    public const int CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG = 0x00040000;
    public const int CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG = 0x00080000;
    public const int CERT_NAME_STR_DISABLE_UTF8_DIR_STR_FLAG = 0x00100000;
    public const int CERT_NAME_STR_ENABLE_PUNYCODE_FLAG = 0x00200000;

    [StructLayout(LayoutKind.Sequential)]
    public struct CRYPT_KEY_PROV_INFO
    {
        [MarshalAs(UnmanagedType.LPWStr)] public string pwszContainerName;
        [MarshalAs(UnmanagedType.LPWStr)] public string pwszProvName;
        public int dwProvType;
        public int dwFlags;
        public int cProvParam;
        public IntPtr rgProvParam;
        public int dwKeySpec;
    }

    public const int AT_KEYEXCHANGE = 1;
    public const int AT_SIGNATURE = 2;

仅供参考,您可以使用
CertificateRequest
类(net472+,netcoreapp2.0+)。是的,使用CertificateRequest我可以生成自签名证书并添加到存储中。但我想尝试使用crypt.dll。
    [DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern IntPtr CertCreateSelfSignCertificate(IntPtr hCryptProvOrNCryptKey, ref CERT_NAME_BLOB pSubjectIssuerBlob, int dwFlags, ref CRYPT_KEY_PROV_INFO pKeyProvInfo,
        IntPtr pSignatureAlgorithm, IntPtr pStartTime, IntPtr pEndTime, IntPtr pExtensions);

    [DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CertFreeCertificateContext(IntPtr pCertContext);

    [StructLayout(LayoutKind.Sequential)]
    public struct CERT_NAME_BLOB
    {
        public int cbData;
        public IntPtr pbData;
    }

    [DllImport("Rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern int UuidCreate(out Guid Uuid);

    [DllImport("rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern int UuidToString(ref Guid uuid, ref IntPtr str);

    [DllImport("rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern int RpcStringFree(ref IntPtr str);

    [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CryptAcquireContext(ref IntPtr phProv, string szContainer, string szProvider, int dwProvType, uint dwFlags);

    [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);

    [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CryptGenKey(IntPtr hProv, uint Algid, int dwFlags, ref IntPtr phKey);

    [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CryptDestroyKey(IntPtr hKey);

    public const int RSA1024BIT_KEY = 0x04000000;
    public const int CRYPT_EXPORTABLE = 0x00000001;

    [DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CertStrToName(uint dwCertEncodingType, string pszX500, uint dwStrType, IntPtr pvReserved,
        [In, Out] byte[] pbEncoded, ref uint pcbEncoded, IntPtr ppszError);

    public const int CRYPT_ASN_ENCODING = 0x00000001;
    public const int CRYPT_NDR_ENCODING = 0x00000002;
    public const int X509_ASN_ENCODING = 0x00000001;
    public const int X509_NDR_ENCODING = 0x00000002;
    public const int PKCS_7_ASN_ENCODING = 0x00010000;
    public const int PKCS_7_NDR_ENCODING = 0x00020000;

    public const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";
    public const int PROV_RSA_FULL = 1;

    public const uint CRYPT_VERIFYCONTEXT = 0xF0000000;
    public const uint CRYPT_NEWKEYSET = 0x00000008;
    public const uint CRYPT_DELETEKEYSET = 0x00000010;
    public const uint CRYPT_MACHINE_KEYSET = 0x00000020;
    public const uint CRYPT_SILENT = 0x00000040;

    public const int CERT_SIMPLE_NAME_STR = 1;
    public const int CERT_OID_NAME_STR = 2;
    public const int CERT_X500_NAME_STR = 3;
    public const int CERT_XML_NAME_STR = 4;

    public const int CERT_NAME_STR_SEMICOLON_FLAG = 0x40000000;
    public const int CERT_NAME_STR_NO_PLUS_FLAG = 0x20000000;
    public const int CERT_NAME_STR_NO_QUOTING_FLAG = 0x10000000;
    public const int CERT_NAME_STR_CRLF_FLAG = 0x08000000;
    public const int CERT_NAME_STR_COMMA_FLAG = 0x04000000;
    public const int CERT_NAME_STR_REVERSE_FLAG = 0x02000000;
    public const int CERT_NAME_STR_FORWARD_FLAG = 0x01000000;

    public const int CERT_NAME_STR_DISABLE_IE4_UTF8_FLAG = 0x00010000;
    public const int CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG = 0x00020000;
    public const int CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG = 0x00040000;
    public const int CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG = 0x00080000;
    public const int CERT_NAME_STR_DISABLE_UTF8_DIR_STR_FLAG = 0x00100000;
    public const int CERT_NAME_STR_ENABLE_PUNYCODE_FLAG = 0x00200000;

    [StructLayout(LayoutKind.Sequential)]
    public struct CRYPT_KEY_PROV_INFO
    {
        [MarshalAs(UnmanagedType.LPWStr)] public string pwszContainerName;
        [MarshalAs(UnmanagedType.LPWStr)] public string pwszProvName;
        public int dwProvType;
        public int dwFlags;
        public int cProvParam;
        public IntPtr rgProvParam;
        public int dwKeySpec;
    }

    public const int AT_KEYEXCHANGE = 1;
    public const int AT_SIGNATURE = 2;