[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);
}
 
原文地址:https://www.cnblogs.com/wuyifu/p/3217255.html