C#创建自签名认证文件的方法
程序员文章站
2023-12-11 20:32:16
本文实例讲述了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#程序设计有所帮助。