C#创建自签名认证文件的方法
作者:jiangzhenyu 发布时间:2021-12-02 03:17:03
标签:C#,签名,认证
本文实例讲述了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#程序设计有所帮助。
0
投稿
猜你喜欢
- 这是一篇入门级文章,高手请略过。在这篇文章中我们将学习如何用 Java 对图像进行剪裁并将剪裁出来的部分单独保存到文件中。我们将通过以下步骤
- 前言最近做项目框架,需要在框架结束的时候,关闭服务器连接,清除部分框架运行lock文件,这里就想到了shutdownhook,顺便学了学Ru
- 本文实例为大家分享了抢红包源码,供大家参考,具体内容如下1. 正确获取红包流程2. 软件介绍2.1 效果图:2.2 功能介绍2.2.1 账号
- HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决
- 本文实例讲述了Android编程简单实现九宫格。分享给大家供大家参考,具体如下:实现的步骤1. 一个整体的容器部分。就是上图中包括整个图片项
- 前言Spring Boot项目一般都是内嵌tomcat或者jetty服务器运行,很少用war包部署到外部的服务容器,即使放到linux中,一
- maven打包时候修改包名称带上git版本号和打包时间使用 maven 插件 git-commit-id-plugin 可以获取项目的git
- 这篇文章主要介绍了java获取当前时间的四种方法代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 前言本文主要给大家介绍了关于Android中GridView布局整体居中的相关内容,是对于自己在项目中遇到问题的一个记录,分享出来供大家参考
- Spring Security登录表单配置1.引入pom依赖创建一个Spring Boot工程,引入Web和Spring Security依
- 本文实例为大家分享了javaweb文件打包批量下载,供大家参考,具体内容如下// 批量下载未批改作业 @RequestMapping(val
- 新建Rest服务接口:[ServiceContract]public interface IService1{ &nb
- 一、简介1.为了防止一个应用程序控制CPU而导致其他应用程序和操作系统本身永远被挂起这一可能情况,操作系统不得不使用某种方式将物理计算分割为
- 前言之前有做个一个自定义报表的查询,这里使用的是一个动态的sql拼接,是前端选择了什么指标就查询什么信息!(这里的指标是多个表的字段,前端随
- 前言本文将演示如何将字符串的单词倒序输出。注意:在这里我不是要将“John” 这样的字符串倒序为成“nhoJ”。这是不一样的,因为它完全倒序
- spring boot 请求后缀匹配spring boot 项目中添加这个类可以实现url不同后缀区分了public class UrlMa
- 首先我们看一下hibernate的主配置文件<!DOCTYPE hibernate-configuration PUBLIC &nbs
- 在【解决方案资源管理器】中找到Form1.cs,单击,快捷键F2重命名为“Login.cs”(命名很
- 1.创建列表(列表可以存储任何类型的数据,在创建列表对象的时候首先要指定你要创建的这个列表要存储什么类型的)(泛型)//创建列表  
- 引言在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户