当前位置: 移动技术网 > IT编程>开发语言>c# > C#创建自签名认证文件的方法

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

2019年07月18日  | 移动技术网IT编程  | 我要评论
本文实例讲述了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#程序设计有所帮助。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网