欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-11-20 23:21:28
本文实例讲述了c#创建自签名认证文件的方法。分享给大家供大家参考。具体如下: using system; using system.runtime.inte...

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