C#创建数字证书并导出为pfx,并使用pfx进行非对称加解密

本文源程序下载:http://download.csdn.net/source/2444494

我的项目当中,考虑到安全性,需要为每个客户端分发一个数字证书,同时使用数字证书中的公私钥来进行数据的加解密。为了完成这个安全模块,特写了如下一个DEMO程序,该DEMO程序包含的功能有:

1:调用.NET2.0的MAKECERT创建含有私钥的数字证书,并存储到个人证书区;

2:将该证书导出为pfx文件,并为其指定一个用来打开pfx文件的password;

3:读取pfx文件,导出pfx中公钥和私钥;

4:用pfx证书中的公钥进行数据的加密,用私钥进行数据的解密;

系统界面:

代码如下:

/// <summary>
        /// 将证书从证书存储区导出,并存储为pfx文件,同时为pfx文件指定打开的密码
        /// 本函数同时也演示如何用公钥进行加密,私钥进行解密
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_toPfxFile_Click(object sender, EventArgs e)
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadWrite);
            X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;
            foreach (X509Certificate2 x509 in storecollection)
            {
                if (x509.Subject == "CN=luminji")
                {
                    Debug.Print(string.Format("certificate name: {0}", x509.Subject));
                    byte[] pfxByte = x509.Export(X509ContentType.Pfx, "123");
                    using (FileStream  fileStream = new FileStream("luminji.pfx", FileMode.Create))
                    {
                        // Write the data to the file, byte by byte.
                        for (int i = 0; i < pfxByte.Length; i++)
                            fileStream.WriteByte(pfxByte[i]);
                        // Set the stream position to the beginning of the file.
                        fileStream.Seek(0, SeekOrigin.Begin);
                        // Read and verify the data.
                        for (int i = 0; i < fileStream.Length; i++)
                        {
                            if (pfxByte[i] != fileStream.ReadByte())
                            {
                                Debug.Print("Error writing data.");
                                return;
                            }
                        }
                        fileStream.Close();
                        Debug.Print("The data was written to {0} " +
                            "and verified.", fileStream.Name);
                    }
                    string myname = "my name is luminji! and i love huzhonghua!";
                    string enStr = this.RSAEncrypt(x509.PublicKey.Key.ToXmlString(false), myname);
                    MessageBox.Show("密文是:" + enStr);
                    string deStr = this.RSADecrypt(x509.PrivateKey.ToXmlString(true), enStr);
                    MessageBox.Show("明文是:" + deStr);
                }
            }
            store.Close();
            store = null;
            storecollection = null;
        }
        /// <summary>
        /// 创建还有私钥的证书
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_createPfx_Click(object sender, EventArgs e)
        {
            string MakeCert = "C://Program Files//Microsoft Visual Studio 8//SDK//v2.0//Bin//makecert.exe";
            string x509Name = "CN=luminji";
            string param = " -pe -ss my -n /"" + x509Name + "/" " ;
            Process p = Process.Start(MakeCert, param);
            p.WaitForExit();
            p.Close();
            MessageBox.Show("over");
        }
        /// <summary>
        /// 从pfx文件读取证书信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_readFromPfxFile(object sender, EventArgs e)
        {
            X509Certificate2 pc = new X509Certificate2("luminji.pfx", "123");
            MessageBox.Show("name:" + pc.SubjectName.Name);
            MessageBox.Show("public:" + pc.PublicKey.ToString());
            MessageBox.Show("private:" + pc.PrivateKey.ToString());
            pc = null;
        }
        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="xmlPrivateKey"></param>
        /// <param name="m_strDecryptString"></param>
        /// <returns></returns>
        public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(xmlPrivateKey);
            byte[] rgb = Convert.FromBase64String(m_strDecryptString);
            byte[] bytes = provider.Decrypt(rgb, false);
            return new UnicodeEncoding().GetString(bytes);
        }
        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="xmlPublicKey"></param>
        /// <param name="m_strEncryptString"></param>
        /// <returns></returns>
        public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(xmlPublicKey);
            byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);
            return Convert.ToBase64String(provider.Encrypt(bytes, false));
        }

  上文是一个示例程序,一个完整的证书工具类如下:

public sealed class DataCertificate
    {
        #region 生成证书
        /// <summary>
        /// 根据指定的证书名和makecert全路径生成证书(包含公钥和私钥,并保存在MY存储区)
        /// </summary>
        /// <param name="subjectName"></param>
        /// <param name="makecertPath"></param>
        /// <returns></returns>
        public static bool CreateCertWithPrivateKey(string subjectName, string makecertPath)
        {
            subjectName = "CN=" + subjectName;
            string param = " -pe -ss my -n /"" + subjectName + "/" ";
            try
            {
                Process p = Process.Start(makecertPath, param);
                p.WaitForExit();
                p.Close();
            }
            catch (Exception e)
            {
                LogRecord.putErrorLog(e.ToString(), "DataCerficate.CreateCertWithPrivateKey");
                return false;
            }
            return true;
        }
        #endregion  

        #region 文件导入导出
        /// <summary>
        /// 从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,
        /// 并导出为pfx文件,同时为其指定一个密码
        /// 并将证书从个人区删除(如果isDelFromstor为true)
        /// </summary>
        /// <param name="subjectName">证书主题,不包含CN=</param>
        /// <param name="pfxFileName">pfx文件名</param>
        /// <param name="password">pfx文件密码</param>
        /// <param name="isDelFromStore">是否从存储区删除</param>
        /// <returns></returns>
        public static bool ExportToPfxFile(string subjectName, string pfxFileName,
            string password, bool isDelFromStore)
        {
            subjectName = "CN=" + subjectName;
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadWrite);
            X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;
            foreach (X509Certificate2 x509 in storecollection)
            {
                if (x509.Subject == subjectName)
                {
                    Debug.Print(string.Format("certificate name: {0}", x509.Subject));  

                    byte[] pfxByte = x509.Export(X509ContentType.Pfx, password);
                    using (FileStream fileStream = new FileStream(pfxFileName, FileMode.Create))
                    {
                        // Write the data to the file, byte by byte.
                        for (int i = 0; i < pfxByte.Length; i++)
                            fileStream.WriteByte(pfxByte[i]);
                        // Set the stream position to the beginning of the file.
                        fileStream.Seek(0, SeekOrigin.Begin);
                        // Read and verify the data.
                        for (int i = 0; i < fileStream.Length; i++)
                        {
                            if (pfxByte[i] != fileStream.ReadByte())
                            {
                                LogRecord.putErrorLog("Export pfx error while verify the pfx file!", "ExportToPfxFile");
                                fileStream.Close();
                                return false;
                            }
                        }
                        fileStream.Close();
                    }
                    if( isDelFromStore == true)
                        store.Remove(x509);
                }
            }
            store.Close();
            store = null;
            storecollection = null;
            return true;
        }
        /// <summary>
        /// 从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,
        /// 并导出为CER文件(即,只含公钥的)
        /// </summary>
        /// <param name="subjectName"></param>
        /// <param name="cerFileName"></param>
        /// <returns></returns>
        public static bool ExportToCerFile(string subjectName, string cerFileName)
        {
            subjectName = "CN=" + subjectName;
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadWrite);
            X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;
            foreach (X509Certificate2 x509 in storecollection)
            {
                if (x509.Subject == subjectName)
                {
                    Debug.Print(string.Format("certificate name: {0}", x509.Subject));
                    //byte[] pfxByte = x509.Export(X509ContentType.Pfx, password);
                    byte[] cerByte = x509.Export(X509ContentType.Cert);
                    using (FileStream fileStream = new FileStream(cerFileName, FileMode.Create))
                    {
                        // Write the data to the file, byte by byte.
                        for (int i = 0; i < cerByte.Length; i++)
                            fileStream.WriteByte(cerByte[i]);
                        // Set the stream position to the beginning of the file.
                        fileStream.Seek(0, SeekOrigin.Begin);
                        // Read and verify the data.
                        for (int i = 0; i < fileStream.Length; i++)
                        {
                            if (cerByte[i] != fileStream.ReadByte())
                            {
                                LogRecord.putErrorLog("Export CER error while verify the CERT file!", "ExportToCERFile");
                                fileStream.Close();
                                return false;
                            }
                        }
                        fileStream.Close();
                    }
                }
            }
            store.Close();
            store = null;
            storecollection = null;
            return true;
        }
        #endregion  

        #region 从证书中获取信息
        /// <summary>
        /// 根据私钥证书得到证书实体,得到实体后可以根据其公钥和私钥进行加解密
        /// 加解密函数使用DEncrypt的RSACryption类
        /// </summary>
        /// <param name="pfxFileName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static X509Certificate2 GetCertificateFromPfxFile(string pfxFileName,
            string password)
        {
            try
            {
                return new X509Certificate2(pfxFileName, password, X509KeyStorageFlags.Exportable);
            }
            catch (Exception e)
            {
                LogRecord.putErrorLog("get certificate from pfx" + pfxFileName + " error:" + e.ToString(),
                    "GetCertificateFromPfxFile");
                return null;
            }
        }
        /// <summary>
        /// 到存储区获取证书
        /// </summary>
        /// <param name="subjectName"></param>
        /// <returns></returns>
        public static X509Certificate2 GetCertificateFromStore(string subjectName)
        {
            subjectName = "CN=" + subjectName;
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadWrite);
            X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;
            foreach (X509Certificate2 x509 in storecollection)
            {
                if (x509.Subject == subjectName)
                {
                    return x509;
                }
            }
            store.Close();
            store = null;
            storecollection = null;
            return null;
        }
        /// <summary>
        /// 根据公钥证书,返回证书实体
        /// </summary>
        /// <param name="cerPath"></param>
        public static X509Certificate2 GetCertFromCerFile(string cerPath)
        {
            try
            {
                return new X509Certificate2(cerPath);
            }
            catch (Exception e)
            {
                LogRecord.putErrorLog(e.ToString(), "DataCertificate.LoadStudentPublicKey");
                return null;
            }
        }
        #endregion
    }

  

时间: 2024-12-16 05:51:08

C#创建数字证书并导出为pfx,并使用pfx进行非对称加解密的相关文章

安全HTTPS-全面详解对称加密,非对称加密,数字签名,数字证书和HTTPS

一,对称加密 所谓对称加密,就是它们在编码时使用的密钥e和解码时一样d(e=d),我们就将其统称为密钥k. 对称加解密的过程如下: 发送端和接收端首先要共享相同的密钥k(即通信前双方都需要知道对应的密钥)才能进行通信.发送端用共享密钥k对明文p进行加密,得到密文c,并将得到的密文发送给接收端,接收端收到密文后,并用其相同的共享密钥k对密文进行解密,得出明文p. 一般加密和解密的算法是公开的,需要保持隐秘的是密钥k,流行的对称加密算法有:DES,Triple-DES,RC2和RC4 对称加密的不足

数字证书KeyTool使用(第二篇)

J2SDK提供了keytool命令行工具,可以根据指定的参数来创建数字证书.生成的证书或证书库默认保存在命令行当前目录下. 1. 创建数字证书  keytool -genkey -v -alias scent -dname "CN=John,OU=MNG,O=Corp,L=Hangzhou,ST=Zhejiang,C=CN" -keyalg RSA -keysize 2048 -keypass 123456 -keystore prospectlib -storepass 123456

Java加密解密与数字证书的操作

1 keytool命令总结 一.创建数字证书 交互模式 使用默认的密钥库.keystore(文件夹是c: Documents and Settingusername)和算法(DSA) keytool -genkey 默认的别名mykey 密钥库中能够存放多个条目(公钥/私钥对和证书),它们在密钥库中以别名(alias)区分. [plain] view plaincopy keytool -genkey -alias mytest -keyalg RSA -keysize 1024 -keysto

JAVA中数字证书的维护及生成方

Java中的keytool.exe可以用来创建数字证书,所有的数字证书是以一条一条(采用别名区别)的形式存入证书库的中,证书库中的一条证书包含该条证书的私钥,公钥和对应的数字证书的信息.证书库中的一条证书可以导出数字证书文件,数字证书文件只包括主体信息和对应的公钥.  每一个证书库是一个文件组成,它有访问密码,在首次创建时,它会自动生成证书库,并要求指定访问证书库的密码.  在创建证书的的时候,需要填写证书的一些信息和证书对应的私钥密码.这些信息包括 CN=xx,OU=xx,O=xx,L=xx,

数字证书

1.简介: 数字证书(certs)又称因特网上的“ID卡”,它包含了由某个受信任组织担保的用户或公司的相关信息. 2.证书的主要内容 数字证书中还包含一组信息,所有这些信息都是由一个官方的证书颁发机构(CA,负责证明用户.计算机和组织的身份)以数字方式签发的,比如对象名称(服务器.组织等).过期时间.证书发布者.来自证书发布者的数字签名.另外,数字证书通常还包括对象的公开密钥,以及对象和所用签名算法的描述性信息. 任何人都可以创建数字证书,但并不是所有人都能够获得受人尊敬的签发权,从而为证书信息

通俗理解数字签名,数字证书和https

前言 最近在开发关于PDF合同文档电子签章的功能,大概意思就是在一份PDF合同上签名,盖章,使其具有法律效应.签章有法律效应必须满足两个条件: 能够证明签名,盖章者是谁,无法抵赖 PDF合同在签章后不能被更改 在纸质合同中,由于签名字迹的不可复制性,盖章的唯一性以及纸质合同对涂改的防范措施(比如金额用大写)可以保证上述两点,从而具备法律效应,那么PDF合同如何保障呢?两个重要的概念就是数字签名和数字证书.这项技术广泛运用于文件认证,数据传输等. 为了弄懂这些,我花了2天时间从加密算法开始,到数字

[转载] 创建为ClickOnce清单签名的.pfx格式数字证书

使用vs2013自动创建的.pfx数字证书默认有效期只有一年,并且“颁发者”.“颁发给”均为当前机器名和当前登陆用户名的组合,其实我们完全可以创建更友好的.pfx数字证书. 打开Microsoft .NET Framework 的SDK命令提示,按以下步骤操作: 1.创建一个自我签署的X.509证书(.cer)和一个.pvk私钥文件,用到makecert工具,命令如下: makecert -r -n "CN= sndnvaps " -b 08/31/2015 -e 08/31/2030

Atitti.数字证书体系cer pfx attilax总结

一.数字证书常见标准 1 数字证书文件格式(cer和pfx)的区别: 1 二.数字证书存储内容 2 X.509是一种非常通用的证书格式. 2 详细特征 2 X.509证书格式 3 一.数字证书常见标准 数字证书体现为一个或一系列相关经过加密的数据文件.常见格式有: 符合PKI ITU-T X509标准,传统标准(.DER .PEM .CER .CRT) 符合PKCS#7 加密消息语法标准(.P7B .P7C .SPC .P7R) 符合PKCS#10 证书请求标准(.p10) 符合PKCS#12

Excel催化剂开源第4波-ClickOnce部署要点之导入数字证书及创建EXCEL信任文件夹

Excel催化刘插件使用Clickonce的部署方式发布插件,以满足用户使用插件过程中,需要对插件进行功能升级时,可以无痛地自动更新推送新版本.但Clickonce部署,对用户环境有较大的要求,前期首次安装,比较波折,但相对于后续的自动更新的回报,笔者自我感觉还是很值得的.Clickonce部署过程中,要求导入数字证书和设置Excel共享路径这两个步骤,本篇开源代码主要讲述这个过程的自动化处理的代码实现,同样用的是Console程序. 为了还原一个干净无侵扰的网络世界,本文将不进行大规模地分发,