这篇文章主要介绍了C#创建自签名认证文件的方法,实例分析了C#自签名认证文件的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
本文实例讲述了C#创建自签名认证文件的方法。分享给大家供大家参考。具体如下:
- using System;
- using System.Runtime.InteropServices;
- using System.Security.Cryptography.X509Certificates;
- using SecureString = System.Security.SecureString;
- using RuntimeHelpers = System.Runtime.CompilerServices.RuntimeHelpers;
- internal class Certificate
- {
- public static byte[] CreateSelfSignCertificatePfx(
- string x500,
- DateTime startTime,
- DateTime endTime)
- {
- byte[] pfxData = CreateSelfSignCertificatePfx(
- x500,
- startTime,
- endTime,
- (SecureString)null);
- return pfxData;
- }
- public static byte[] CreateSelfSignCertificatePfx(
- string x500,
- DateTime startTime,
- DateTime endTime,
- string insecurePassword)
- {
- byte[] pfxData;
- SecureString password = null;
- try
- {
- if (!string.IsNullOrEmpty(insecurePassword))
- {
- password = new SecureString();
- foreach (char ch in insecurePassword)
- {
- password.AppendChar(ch);
- }
- password.MakeReadOnly();
- }
- pfxData = CreateSelfSignCertificatePfx(
- x500,
- startTime,
- endTime,
- password);
- }
- finally
- {
- if (password != null)
- {
- password.Dispose();
- }
- }
- return pfxData;
- }
- public static byte[] CreateSelfSignCertificatePfx(
- string x500,
- DateTime startTime,
- DateTime endTime,
- SecureString password)
- {
- byte[] pfxData;
- if (x500 == null)
- {
- x500 = "";
- }
- SystemTime startSystemTime = ToSystemTime(startTime);
- SystemTime endSystemTime = ToSystemTime(endTime);
- string containerName = Guid.NewGuid().ToString();
- GCHandle dataHandle = new GCHandle();
- IntPtr providerContext = IntPtr.Zero;
- IntPtr cryptKey = IntPtr.Zero;
- IntPtr certContext = IntPtr.Zero;
- IntPtr certStore = IntPtr.Zero;
- IntPtr storeCertContext = IntPtr.Zero;
- IntPtr passwordPtr = IntPtr.Zero;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- Check(NativeMethods.CryptAcquireContextW(
- out providerContext,
- containerName,
- null,
- 1, // PROV_RSA_FULL
- 8)); // CRYPT_NEWKEYSET
- Check(NativeMethods.CryptGenKey(
- providerContext,
- 1, // AT_KEYEXCHANGE
- 1, // CRYPT_EXPORTABLE
- out cryptKey));
- IntPtr errorStringPtr;
- int nameDataLength = 0;
- byte[] nameData;
- // errorStringPtr gets a pointer into the middle of the x500 string,
- // so x500 needs to be pinned until after we've copied the value
- // of errorStringPtr.
- dataHandle = GCHandle.Alloc(x500, GCHandleType.Pinned);
- if (!NativeMethods.CertStrToNameW(
- 0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
- dataHandle.AddrOfPinnedObject(),
- 3, // CERT_X500_NAME_STR = 3
- IntPtr.Zero,
- null,
- ref nameDataLength,
- out errorStringPtr))
- {
- string error = Marshal.PtrToStringUni(errorStringPtr);
- throw new ArgumentException(error);
- }
- nameData = new byte[nameDataLength];
- if (!NativeMethods.CertStrToNameW(
- 0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
- dataHandle.AddrOfPinnedObject(),
- 3, // CERT_X500_NAME_STR = 3
- IntPtr.Zero,
- nameData,
- ref nameDataLength,
- out errorStringPtr))
- {
- string error = Marshal.PtrToStringUni(errorStringPtr);
- throw new ArgumentException(error);
- }
- dataHandle.Free();
- dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
- CryptoApiBlob nameBlob = new CryptoApiBlob(
- nameData.Length,
- dataHandle.AddrOfPinnedObject());
- CryptKeyProviderInformation kpi = new CryptKeyProviderInformation();
- kpi.ContainerName = containerName;
- kpi.ProviderType = 1; // PROV_RSA_FULL
- kpi.KeySpec = 1; // AT_KEYEXCHANGE
- certContext = NativeMethods.CertCreateSelfSignCertificate(
- providerContext,
- ref nameBlob,
- 0,
- ref kpi,
- IntPtr.Zero, // default = SHA1RSA
- ref startSystemTime,
- ref endSystemTime,
- IntPtr.Zero);
- Check(certContext != IntPtr.Zero);
- dataHandle.Free();
- certStore = NativeMethods.CertOpenStore(
- "Memory", // sz_CERT_STORE_PROV_MEMORY
- 0,
- IntPtr.Zero,
- 0x2000, // CERT_STORE_CREATE_NEW_FLAG
- IntPtr.Zero);
- Check(certStore != IntPtr.Zero);
- Check(NativeMethods.CertAddCertificateContextToStore(
- certStore,
- certContext,
- 1, // CERT_STORE_ADD_NEW
- out storeCertContext));
- NativeMethods.CertSetCertificateContextProperty(
- storeCertContext,
- 2, // CERT_KEY_PROV_INFO_PROP_ID
- 0,
- ref kpi);
- if (password != null)
- {
- passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
- }
- CryptoApiBlob pfxBlob = new CryptoApiBlob();
- Check(NativeMethods.PFXExportCertStoreEx(
- certStore,
- ref pfxBlob,
- passwordPtr,
- IntPtr.Zero,
- 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
- pfxData = new byte[pfxBlob.DataLength];
- dataHandle = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
- pfxBlob.Data = dataHandle.AddrOfPinnedObject();
- Check(NativeMethods.PFXExportCertStoreEx(
- certStore,
- ref pfxBlob,
- passwordPtr,
- IntPtr.Zero,
- 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
- dataHandle.Free();
- }
- finally
- {
- if (passwordPtr != IntPtr.Zero)
- {
- Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
- }
- if (dataHandle.IsAllocated)
- {
- dataHandle.Free();
- }
- if (certContext != IntPtr.Zero)
- {
- NativeMethods.CertFreeCertificateContext(certContext);
- }
- if (storeCertContext != IntPtr.Zero)
- {
- NativeMethods.CertFreeCertificateContext(storeCertContext);
- }
- if (certStore != IntPtr.Zero)
- {
- NativeMethods.CertCloseStore(certStore, 0);
- }
- if (cryptKey != IntPtr.Zero)
- {
- NativeMethods.CryptDestroyKey(cryptKey);
- }
- if (providerContext != IntPtr.Zero)
- {
- NativeMethods.CryptReleaseContext(providerContext, 0);
- NativeMethods.CryptAcquireContextW(
- out providerContext,
- containerName,
- null,
- 1, // PROV_RSA_FULL
- 0x10); // CRYPT_DELETEKEYSET
- }
- }
- return pfxData;
- }
- private static SystemTime ToSystemTime(DateTime dateTime)
- {
- long fileTime = dateTime.ToFileTime();
- SystemTime systemTime;
- Check(NativeMethods.FileTimeToSystemTime(ref fileTime, out systemTime));
- return systemTime;
- }
- private static void Check(bool nativeCallSucceeded)
- {
- if (!nativeCallSucceeded)
- {
- int error = Marshal.GetHRForLastWin32Error();
- Marshal.ThrowExceptionForHR(error);
- }
- }
- [StructLayout(LayoutKind.Sequential)]
- private struct SystemTime
- {
- public short Year;
- public short Month;
- public short DayOfWeek;
- public short Day;
- public short Hour;
- public short Minute;
- public short Second;
- public short Milliseconds;
- }
- [StructLayout(LayoutKind.Sequential)]
- private struct CryptoApiBlob
- {
- public int DataLength;
- public IntPtr Data;
- public CryptoApiBlob(int dataLength, IntPtr data)
- {
- this.DataLength = dataLength;
- this.Data = data;
- }
- }
- [StructLayout(LayoutKind.Sequential)]
- private struct CryptKeyProviderInformation
- {
- [MarshalAs(UnmanagedType.LPWStr)] public string ContainerName;
- [MarshalAs(UnmanagedType.LPWStr)] public string ProviderName;
- public int ProviderType;
- public int Flags;
- public int ProviderParameterCount;
- public IntPtr ProviderParameters; // PCRYPT_KEY_PROV_PARAM
- public int KeySpec;
- }
- private static class NativeMethods
- {
- [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool FileTimeToSystemTime(
- [In] ref long fileTime,
- out SystemTime systemTime);
- [DllImport("AdvApi32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CryptAcquireContextW(
- out IntPtr providerContext,
- [MarshalAs(UnmanagedType.LPWStr)] string container,
- [MarshalAs(UnmanagedType.LPWStr)] string provider,
- int providerType,
- int flags);
- [DllImport("AdvApi32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CryptReleaseContext(
- IntPtr providerContext,
- int flags);
- [DllImport("AdvApi32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CryptGenKey(
- IntPtr providerContext,
- int algorithmId,
- int flags,
- out IntPtr cryptKeyHandle);
- [DllImport("AdvApi32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CryptDestroyKey(
- IntPtr cryptKeyHandle);
- [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CertStrToNameW(
- int certificateEncodingType,
- IntPtr x500,
- int strType,
- IntPtr reserved,
- [MarshalAs(UnmanagedType.LPArray)] [Out] byte[] encoded,
- ref int encodedLength,
- out IntPtr errorString);
- [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
- public static extern IntPtr CertCreateSelfSignCertificate(
- IntPtr providerHandle,
- [In] ref CryptoApiBlob subjectIssuerBlob,
- int flags,
- [In] ref CryptKeyProviderInformation keyProviderInformation,
- IntPtr signatureAlgorithm,
- [In] ref SystemTime startTime,
- [In] ref SystemTime endTime,
- IntPtr extensions);
- [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CertFreeCertificateContext(
- IntPtr certificateContext);
- [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
- public static extern IntPtr CertOpenStore(
- [MarshalAs(UnmanagedType.LPStr)] string storeProvider,
- int messageAndCertificateEncodingType,
- IntPtr cryptProvHandle,
- int flags,
- IntPtr parameters);
- [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CertCloseStore(
- IntPtr certificateStoreHandle,
- int flags);
- [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CertAddCertificateContextToStore(
- IntPtr certificateStoreHandle,
- IntPtr certificateContext,
- int addDisposition,
- out IntPtr storeContextPtr);
- [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CertSetCertificateContextProperty(
- IntPtr certificateContext,
- int propertyId,
- int flags,
- [In] ref CryptKeyProviderInformation data);
- [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool PFXExportCertStoreEx(
- IntPtr certificateStoreHandle,
- ref CryptoApiBlob pfxBlob,
- IntPtr password,
- IntPtr reserved,
- int flags);
- }
- }
希望本文所述对大家的C#程序设计有所帮助。
新闻热点
疑难解答