X509加密证书

1.相关名词

证书文件通常以.cer, .crt结尾
公钥文件通常以.pem结尾
私钥文件通常以.key结尾
.pfx 一种文件存储格式, pkcs12是它的实现, 通常里面同时包含私钥, 公钥, 证书, 方便存储和传播
公钥/私钥用于数据加密, 公钥可以发布给任何人, 私钥必须保密
用公钥加密
用私钥解密
客户端通过公钥将数据加密传递给我,只有我手中的私钥可以解密,这就是SSL,这里的秘钥就是key文件。

2.makecert

Microsoft Visual Studio 安装目录可以找到 makecert.exe文件,通过makecert可以在本地生成一个证书。
我的VS版本为2017 运行文件路径为
string MakeCert = @"C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\makecert.exe"
makecert --help 用来验证是否可以生成证书

参数意义
-r: 自签名
-pe: 将所生成的私钥标记为可导出。这样可将私钥包括在证书中。
-n "cn=MyCA": 证书的subject name,.net自带类库中有X509Store类,可以在store中根据证书subject name,来找到改证书
store参考:X509Store 类
-$ commercial:指明证书商业使用。
-a:指定签名算法。必须是 md5(默认值)或 sha1。
-b 08/05/2010:证书有效期的开始时间,默认为证书的创建日期。格式为:mm/dd/yyyy
-e 01/01/2012:指定有效期的结束时间。默认为 12/31/2039 11:59:59 GMT。格式同上
-ss my:证书产生到my个人store区
-sr currentuser:保持到计算机当前个人用户区,其他用户登录系统后则看不到该证书。

3.C#语言操作代码示例

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace TcpServer.Utils
{
    public class CertificateUtil
    {
        ///  
        /// 将证书从证书存储区导出,并存储为pfx文件,同时为pfx文件指定打开的密码 
        /// 本函数同时也演示如何用公钥进行加密,私钥进行解密 
        ///  
        public void OutPfxFile(string name, string password)
        {
            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=" + name)
                {
                    Debug.Print(string.Format("certificate name: {0}", x509.Subject));
                    byte[] pfxByte = x509.Export(X509ContentType.Pfx, password);
                    using (FileStream fileStream = new FileStream(name + ".pfx", FileMode.Create))
                    {
                        // 写数据到文件
                        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);
                        //读取并校验数据
                        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 = "这是测试文本数据 this is test text data";
                    string enStr = this.RSAEncrypt(x509.PublicKey.Key.ToXmlString(false), myname);
                    Console.WriteLine("密文是:" + enStr);
                    string deStr = this.RSADecrypt(x509.PrivateKey.ToXmlString(true), enStr);
                    Console.WriteLine("明文是:" + deStr);
                }
            }
            store.Close();
            store = null;
            storecollection = null;
        }

        ///  
        /// 从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书, 
        /// 并导出为CER文件(即,只含公钥的) 
        ///  
        public static bool OutCerFile(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[] cerByte = x509.Export(X509ContentType.Cert);
                    using (FileStream fileStream = new FileStream(cerFileName, FileMode.Create))
                    {
                        for (int i = 0; i < cerByte.Length; i++)
                            fileStream.WriteByte(cerByte[i]);
                        fileStream.Seek(0, SeekOrigin.Begin);
                        for (int i = 0; i < fileStream.Length; i++)
                        {
                            if (cerByte[i] != fileStream.ReadByte())
                            {
                                Log.WriteLog("Export CER error while verify the CERT file!" + "ExportToCERFile");
                                fileStream.Close();
                                return false;
                            }
                        }
                        fileStream.Close();
                    }
                }
            }
            store.Close();
            store = null;
            storecollection = null;
            return true;
        }

        ///  
        /// 根据指定的证书名和makecert全路径生成证书(包含公钥和私钥,并保存在MY存储区) 
        ///  
        public void CreateBook(string name, string path)
        {
            //string MakeCert = @"C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\makecert.exe";

            string x509Name = "CN=" + name;
            string param = " -pe -ss my -n \"" + x509Name + "\" ";
            Process p = Process.Start(path, param);
            p.WaitForExit();
            p.Close();
        }
        ///  
        /// 从pfx文件读取证书信息 
        ///  
        private void ReadPfxFile(string name, string password)
        {
            X509Certificate2 pc = new X509Certificate2(name + ".pfx", password);
            Console.WriteLine("name:" + pc.SubjectName.Name);
            Console.WriteLine("public:" + pc.PublicKey.ToString());
            Console.WriteLine("private:" + pc.PrivateKey.ToString());
            pc = null;
        }
        ///  
        ///使用私钥 RSA解密 
        ///  
        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);
        }
        ///  
        ///使用公钥 RSA加密 
        ///  
        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));
        }
        ///  
        /// 根据私钥证书得到证书实体,得到实体后可以根据其公钥和私钥进行加解密 
        /// 加解密函数使用DEncrypt的RSACryption类 
        ///  
        public static X509Certificate2 GetCertificateFromPfxFile(string pfxFileName,
            string password)
        {
            try
            {
                return new X509Certificate2(pfxFileName, password, X509KeyStorageFlags.Exportable);
            }
            catch (Exception e)
            {
                Log.WriteLog("get certificate from pfx" + pfxFileName + " error:" + e.ToString() +
                    "GetCertificateFromPfxFile");
                return null;
            }
        }
        ///  
        /// 到存储区获取证书 
        ///  
        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;
        }
        ///  
        /// 根据公钥证书,返回证书实体 
        ///  
        public static X509Certificate2 GetCertFromCerFile(string cerPath)
        {
            try
            {
                return new X509Certificate2(cerPath);
            }
            catch (Exception e)
            {
                Log.WriteLog(e.ToString() + "DataCertificate.LoadStudentPublicKey");
                return null;
            }
        }
    }
}

你可能感兴趣的:(X509加密证书)