首页 > 编程 > C# > 正文

C#创建自签名认证文件的方法

2020-01-24 01:37:25
字体:
来源:转载
供稿:网友

本文实例讲述了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#程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表