C# CertCreateSelfSignCertificate返回null,错误代码87
我在C#中使用crypt api创建SSL证书时遇到问题,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.
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;