zoukankan      html  css  js  c++  java
  • [C#.NET] X509 數位電子簽章

    摘自: http://www.dotblogs.com.tw/yc421206/archive/2012/06/30/73140.aspx

    在上篇[C#.NET] 字串及檔案,利用 RSA 演算法加解密 後半段提到了使用簽章來証明訊息,當時是使用RSA類別提供的Hash演算法來進行簽章動作,根據維基百科所述,我們可以使用數位簽章來提昇安全性。

    http://zh.wikipedia.org/zh-hant/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95

    image

     

    http://zh.wikipedia.org/wiki/%E6%95%B0%E5%AD%97%E8%AE%A4%E8%AF%81

    image

     

    這是我自己建的CA中心,當然它所產生出的憑證預設是不會被系統所信任的,安裝時可以自己加到信任區,商業用的憑証可花錢購買,來得到系統信任,這是我從咱們 方丈 那裡得到的知識。

    image

    image


    匯入憑証:

    可將下載到憑證,雙擊兩下,加入信任區。

    SNAGHTML579f3fb

    SNAGHTML57a2dfe

    SNAGHTML57a8ee3

    SNAGHTML57abf35

    SNAGHTML57beb25

     

    或是開啟MMC控制台

    開始程式集→輸入MMC

    SNAGHTML5750c1d

    SNAGHTML5756d10

    SNAGHTML575b68e

    SNAGHTML5762d34

    SNAGHTML576a494

    SNAGHTML576e06b

    SNAGHTML5770fb5

    SNAGHTML57875c7

     

    不管是雙擊兩下還是由MMC控制匯入,都可在這裡查到你匯入的憑証。

    SNAGHTML577c982

     

    當然也可以匯出,有需要的人就再自己自行操作了,我怕篇幅太長。

    SNAGHTML57e51a5


    檔案保存格式

    1. 帶有私鑰的憑證以pfx為副檔名
    2. 沒有私鑰以DER編碼為格式的憑証用cer為副檔名
    3. 沒有私鑰以BASE64編碼為格式的憑証用cer為副檔名

     

     

     

    從我自己建立的CA憑證中心取得的憑證,在VS2010開起來長這樣。

    image


    憑証的用法很簡單,只要調用 X509Certificate2 類別

    public X509Certificate2 CreateCertificat(string CertFile, string Password)
    {
        X509Certificate2 cert;
        if (string.IsNullOrEmpty(Password))
        {
            cert = new X509Certificate2(CertFile);
        }
        else
        {
            cert = new X509Certificate2(CertFile, Password);
        }
        return cert;
    }
     
    我們可以透過一些檢查來驗証憑証是否有效。
    public void VerifyCertificate(X509Certificate2 Cert)
    {
        if (Cert == null) throw new ArgumentNullException("Ccert");
        X509Chain chain = new X509Chain();
    
        chain.ChainPolicy.RevocationMode = X509RevocationMode.OnLine;
        chain.Build(Cert);
    
        if (Cert.NotAfter <= DateTime.Now)
        {
            throw new ApplicationException(string.Format("憑証過期"));
        }
    }

    憑證匯入並儲存

    public X509Certificate2 ImportCertificate(string CertFile, string Password)
    {
        var cert = this.CreateCertificate(CertFile, Password);
        X509Store store = new X509Store(this.StoreName, this.Location);
        store.Open(OpenFlags.ReadWrite);
        store.Add(cert);
        store.Close();
        return cert;
    }
    憑証匯出
    public bool ExportCertificate(string CertSubjectName, string Password, string ExportFile)
    {
        if (CertSubjectName == null) throw new ArgumentNullException("CertSubjectName");
        if (ExportFile == null) throw new ArgumentNullException("ExportFile");
        X509Store store = new X509Store(this.StoreName, this.Location);
        store.Open(OpenFlags.ReadOnly);
        FileStream fileStream = null;
        try
        {
            fileStream = new FileStream(ExportFile, FileMode.Create, FileAccess.Write);
            foreach (X509Certificate2 cert in store.Certificates)
            {
                if (cert.Subject == CertSubjectName)
                {
                    byte[] CertByte;
    
                    if (string.IsNullOrEmpty(Password))
                    {
                        CertByte = cert.Export(X509ContentType);
                    }
                    else
                    {
                        CertByte = cert.Export(X509ContentType, Password);
                    }
                    fileStream.Write(CertByte, 0, CertByte.Length);
                    return true;
                }
            }
        }
        finally
        {
            if (fileStream != null) fileStream.Dispose();
            store.Close();
        }
        return false;
    }
     
    完整範例
    public class RsaCryptService
    {
        private X509ContentType _x509ContentType = X509ContentType.Cert;
    
        public X509ContentType X509ContentType
        {
            get { return _x509ContentType; }
            set { _x509ContentType = value; }
        }
    
        private StoreName _storeName = StoreName.My;
    
        public StoreName StoreName
        {
            get { return _storeName; }
            set { _storeName = value; }
        }
    
        private StoreLocation _locationr = StoreLocation.CurrentUser;
    
        public StoreLocation Location
        {
            get { return _locationr; }
            set { _locationr = value; }
        }
    
        public X509Certificate2 CreateCertificate(string CertFile)
        {
            if (CertFile == null) throw new ArgumentNullException("CertFile");
            return this.CreateCertificate(CertFile, "");
        }
    
        public X509Certificate2 CreateCertificate(string CertFile, string Password)
        {
            if (CertFile == null) throw new ArgumentNullException("CertFile");
            if (Password == null) throw new ArgumentNullException("Password");
            X509Certificate2 cert = null;
            if (string.IsNullOrEmpty(Password))
            {
                cert = new X509Certificate2(CertFile);
            }
            else
            {
                cert = new X509Certificate2(CertFile, Password);
            }
            return cert;
        }
    
        public X509Certificate2 ImportCertificate(string CertFile)
        {
            if (CertFile == null) throw new ArgumentNullException("CertFile");
            return this.ImportCertificate(CertFile, "");
        }
    
        public X509Certificate2 ImportCertificate(string CertFile, string Password)
        {
            if (CertFile == null) throw new ArgumentNullException("CertFile");
            if (Password == null) throw new ArgumentNullException("Password");
            var cert = this.CreateCertificate(CertFile, Password);
            if (cert == null) return null;
    
            X509Store store = new X509Store(this.StoreName, this.Location);
            store.Open(OpenFlags.ReadWrite);
            store.Add(cert);
            store.Close();
            return cert;
        }
    
        public bool ExportCertificate(string CertSubjectName, string ExportFile)
        {
            if (CertSubjectName == null) throw new ArgumentNullException("CertSubjectName");
            if (ExportFile == null) throw new ArgumentNullException("ExportFile");
            return ExportCertificate(CertSubjectName, null, ExportFile);
        }
    
        public bool ExportCertificate(string CertSubjectName, string Password, string ExportFile)
        {
            if (CertSubjectName == null) throw new ArgumentNullException("CertSubjectName");
            if (ExportFile == null) throw new ArgumentNullException("ExportFile");
            X509Store store = new X509Store(this.StoreName, this.Location);
            store.Open(OpenFlags.ReadOnly);
            FileStream fileStream = null;
            try
            {
                fileStream = new FileStream(ExportFile, FileMode.Create, FileAccess.Write);
                foreach (X509Certificate2 cert in store.Certificates)
                {
                    if (cert.Subject == CertSubjectName)
                    {
                        byte[] CertByte;
    
                        if (string.IsNullOrEmpty(Password))
                        {
                            CertByte = cert.Export(X509ContentType);
                        }
                        else
                        {
                            CertByte = cert.Export(X509ContentType, Password);
                        }
                        fileStream.Write(CertByte, 0, CertByte.Length);
                        return true;
                    }
                }
            }
            finally
            {
                if (fileStream != null) fileStream.Dispose();
                store.Close();
            }
            return false;
        }
    
        public void VerifyCertificate(X509Certificate2 Cert)
        {
            if (Cert == null) throw new ArgumentNullException("Ccert");
            X509Chain chain = new X509Chain();
    
            chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            chain.Build(Cert);
    
            if (Cert.NotAfter <= DateTime.Now)
            {
                throw new ApplicationException(string.Format("憑証過期"));
            }
        }
    }
     
    憑証匯入單元測試
    [TestMethod()]
    [DeploymentItem("artag.certnew.cer")]
    public void ImportCertificatGetCertTest()
    {
        RsaCryptService target = new RsaCryptService();
        target.Location = StoreLocation.CurrentUser;
        target.StoreName = StoreName.AuthRoot;
        target.ImportCertificate("artag.certnew.cer");
    }
     
    憑証匯出單元測試
    [TestMethod()]
    public void ExportCertificatTest()
    {
        RsaCryptService target = new RsaCryptService();
        target.Location = StoreLocation.CurrentUser;
        target.StoreName = StoreName.AuthRoot;
        string CertName = "CN=artag-AD-CA, DC=artag, DC=com";
    
        string ExportFile = "export.cer";
        var actual = target.ExportCertificate(CertName, ExportFile);
        Assert.AreEqual(true, actual);
    }
    憑証檢查單元測試
    [TestMethod()]
    [DeploymentItem("artag.certnew.cer")]
    public void VerifyCertificateTest()
    {
        RsaCryptService target = new RsaCryptService();
        X509Certificate2 cert = target.CreateCertificate("artag.certnew.cer");
        target.VerifyCertificate(cert);
    }
     
  • 相关阅读:
    JAVA不可变类(immutable)机制与String的不可变性
    如何高效学习
    [细品java]ThreadLocal源码学习
    Spring 入门知识点笔记整理
    spring远程服务知识梳理
    Spring Security 入门详解
    Selenium 安装 geckdriver Firefox 对应关系 历史版本下载
    Redhat linux 下 Jmeter 非GUI界面执行压力测试
    Spring Boot 进程守护 修改启动端口号 Spring Boot 监听端口被占用无法启动
    Redhat Linux 部署maven环境
  • 原文地址:https://www.cnblogs.com/wuyifu/p/3217255.html
Copyright © 2011-2022 走看看