C#创建自签名认证文件的方法
本文实例讲述了C#创建自签名认证文件的方法。分享给大家供大家参考。具体如下:
usingSystem;
usingSystem.Runtime.InteropServices;
usingSystem.Security.Cryptography.X509Certificates;
usingSecureString=System.Security.SecureString;
usingRuntimeHelpers=System.Runtime.CompilerServices.RuntimeHelpers;
internalclassCertificate
{
publicstaticbyte[]CreateSelfSignCertificatePfx(
stringx500,
DateTimestartTime,
DateTimeendTime)
{
byte[]pfxData=CreateSelfSignCertificatePfx(
x500,
startTime,
endTime,
(SecureString)null);
returnpfxData;
}
publicstaticbyte[]CreateSelfSignCertificatePfx(
stringx500,
DateTimestartTime,
DateTimeendTime,
stringinsecurePassword)
{
byte[]pfxData;
SecureStringpassword=null;
try
{
if(!string.IsNullOrEmpty(insecurePassword))
{
password=newSecureString();
foreach(charchininsecurePassword)
{
password.AppendChar(ch);
}
password.MakeReadOnly();
}
pfxData=CreateSelfSignCertificatePfx(
x500,
startTime,
endTime,
password);
}
finally
{
if(password!=null)
{
password.Dispose();
}
}
returnpfxData;
}
publicstaticbyte[]CreateSelfSignCertificatePfx(
stringx500,
DateTimestartTime,
DateTimeendTime,
SecureStringpassword)
{
byte[]pfxData;
if(x500==null)
{
x500="";
}
SystemTimestartSystemTime=ToSystemTime(startTime);
SystemTimeendSystemTime=ToSystemTime(endTime);
stringcontainerName=Guid.NewGuid().ToString();
GCHandledataHandle=newGCHandle();
IntPtrproviderContext=IntPtr.Zero;
IntPtrcryptKey=IntPtr.Zero;
IntPtrcertContext=IntPtr.Zero;
IntPtrcertStore=IntPtr.Zero;
IntPtrstoreCertContext=IntPtr.Zero;
IntPtrpasswordPtr=IntPtr.Zero;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
Check(NativeMethods.CryptAcquireContextW(
outproviderContext,
containerName,
null,
1,//PROV_RSA_FULL
8));//CRYPT_NEWKEYSET
Check(NativeMethods.CryptGenKey(
providerContext,
1,//AT_KEYEXCHANGE
1,//CRYPT_EXPORTABLE
outcryptKey));
IntPtrerrorStringPtr;
intnameDataLength=0;
byte[]nameData;
//errorStringPtrgetsapointerintothemiddleofthex500string,
//sox500needstobepinneduntilafterwe'vecopiedthevalue
//oferrorStringPtr.
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,
refnameDataLength,
outerrorStringPtr))
{
stringerror=Marshal.PtrToStringUni(errorStringPtr);
thrownewArgumentException(error);
}
nameData=newbyte[nameDataLength];
if(!NativeMethods.CertStrToNameW(
0x00010001,//X509_ASN_ENCODING|PKCS_7_ASN_ENCODING
dataHandle.AddrOfPinnedObject(),
3,//CERT_X500_NAME_STR=3
IntPtr.Zero,
nameData,
refnameDataLength,
outerrorStringPtr))
{
stringerror=Marshal.PtrToStringUni(errorStringPtr);
thrownewArgumentException(error);
}
dataHandle.Free();
dataHandle=GCHandle.Alloc(nameData,GCHandleType.Pinned);
CryptoApiBlobnameBlob=newCryptoApiBlob(
nameData.Length,
dataHandle.AddrOfPinnedObject());
CryptKeyProviderInformationkpi=newCryptKeyProviderInformation();
kpi.ContainerName=containerName;
kpi.ProviderType=1;//PROV_RSA_FULL
kpi.KeySpec=1;//AT_KEYEXCHANGE
certContext=NativeMethods.CertCreateSelfSignCertificate(
providerContext,
refnameBlob,
0,
refkpi,
IntPtr.Zero,//default=SHA1RSA
refstartSystemTime,
refendSystemTime,
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
outstoreCertContext));
NativeMethods.CertSetCertificateContextProperty(
storeCertContext,
2,//CERT_KEY_PROV_INFO_PROP_ID
0,
refkpi);
if(password!=null)
{
passwordPtr=Marshal.SecureStringToCoTaskMemUnicode(password);
}
CryptoApiBlobpfxBlob=newCryptoApiBlob();
Check(NativeMethods.PFXExportCertStoreEx(
certStore,
refpfxBlob,
passwordPtr,
IntPtr.Zero,
7));//EXPORT_PRIVATE_KEYS|REPORT_NO_PRIVATE_KEY|REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
pfxData=newbyte[pfxBlob.DataLength];
dataHandle=GCHandle.Alloc(pfxData,GCHandleType.Pinned);
pfxBlob.Data=dataHandle.AddrOfPinnedObject();
Check(NativeMethods.PFXExportCertStoreEx(
certStore,
refpfxBlob,
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(
outproviderContext,
containerName,
null,
1,//PROV_RSA_FULL
0x10);//CRYPT_DELETEKEYSET
}
}
returnpfxData;
}
privatestaticSystemTimeToSystemTime(DateTimedateTime)
{
longfileTime=dateTime.ToFileTime();
SystemTimesystemTime;
Check(NativeMethods.FileTimeToSystemTime(reffileTime,outsystemTime));
returnsystemTime;
}
privatestaticvoidCheck(boolnativeCallSucceeded)
{
if(!nativeCallSucceeded)
{
interror=Marshal.GetHRForLastWin32Error();
Marshal.ThrowExceptionForHR(error);
}
}
[StructLayout(LayoutKind.Sequential)]
privatestructSystemTime
{
publicshortYear;
publicshortMonth;
publicshortDayOfWeek;
publicshortDay;
publicshortHour;
publicshortMinute;
publicshortSecond;
publicshortMilliseconds;
}
[StructLayout(LayoutKind.Sequential)]
privatestructCryptoApiBlob
{
publicintDataLength;
publicIntPtrData;
publicCryptoApiBlob(intdataLength,IntPtrdata)
{
this.DataLength=dataLength;
this.Data=data;
}
}
[StructLayout(LayoutKind.Sequential)]
privatestructCryptKeyProviderInformation
{
[MarshalAs(UnmanagedType.LPWStr)]publicstringContainerName;
[MarshalAs(UnmanagedType.LPWStr)]publicstringProviderName;
publicintProviderType;
publicintFlags;
publicintProviderParameterCount;
publicIntPtrProviderParameters;//PCRYPT_KEY_PROV_PARAM
publicintKeySpec;
}
privatestaticclassNativeMethods
{
[DllImport("kernel32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolFileTimeToSystemTime(
[In]reflongfileTime,
outSystemTimesystemTime);
[DllImport("AdvApi32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCryptAcquireContextW(
outIntPtrproviderContext,
[MarshalAs(UnmanagedType.LPWStr)]stringcontainer,
[MarshalAs(UnmanagedType.LPWStr)]stringprovider,
intproviderType,
intflags);
[DllImport("AdvApi32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCryptReleaseContext(
IntPtrproviderContext,
intflags);
[DllImport("AdvApi32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCryptGenKey(
IntPtrproviderContext,
intalgorithmId,
intflags,
outIntPtrcryptKeyHandle);
[DllImport("AdvApi32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCryptDestroyKey(
IntPtrcryptKeyHandle);
[DllImport("Crypt32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCertStrToNameW(
intcertificateEncodingType,
IntPtrx500,
intstrType,
IntPtrreserved,
[MarshalAs(UnmanagedType.LPArray)][Out]byte[]encoded,
refintencodedLength,
outIntPtrerrorString);
[DllImport("Crypt32.dll",SetLastError=true,ExactSpelling=true)]
publicstaticexternIntPtrCertCreateSelfSignCertificate(
IntPtrproviderHandle,
[In]refCryptoApiBlobsubjectIssuerBlob,
intflags,
[In]refCryptKeyProviderInformationkeyProviderInformation,
IntPtrsignatureAlgorithm,
[In]refSystemTimestartTime,
[In]refSystemTimeendTime,
IntPtrextensions);
[DllImport("Crypt32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCertFreeCertificateContext(
IntPtrcertificateContext);
[DllImport("Crypt32.dll",SetLastError=true,ExactSpelling=true)]
publicstaticexternIntPtrCertOpenStore(
[MarshalAs(UnmanagedType.LPStr)]stringstoreProvider,
intmessageAndCertificateEncodingType,
IntPtrcryptProvHandle,
intflags,
IntPtrparameters);
[DllImport("Crypt32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCertCloseStore(
IntPtrcertificateStoreHandle,
intflags);
[DllImport("Crypt32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCertAddCertificateContextToStore(
IntPtrcertificateStoreHandle,
IntPtrcertificateContext,
intaddDisposition,
outIntPtrstoreContextPtr);
[DllImport("Crypt32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolCertSetCertificateContextProperty(
IntPtrcertificateContext,
intpropertyId,
intflags,
[In]refCryptKeyProviderInformationdata);
[DllImport("Crypt32.dll",SetLastError=true,ExactSpelling=true)]
[return:MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolPFXExportCertStoreEx(
IntPtrcertificateStoreHandle,
refCryptoApiBlobpfxBlob,
IntPtrpassword,
IntPtrreserved,
intflags);
}
}
希望本文所述对大家的C#程序设计有所帮助。