摘自: 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

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

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


匯入憑証:

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

或是開啟MMC控制台

開始程式集→輸入MMC

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

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


檔案保存格式

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

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


憑証的用法很簡單,只要調用 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);
}
 

[C#.NET] X509 數位電子簽章的更多相关文章

  1. [C#.NET] 使用 X509 數位電子簽章 加解密

    摘自: http://www.dotblogs.com.tw/yc421206/archive/2012/06/30/73150.aspx 上篇提到了使用X509的的憑證使用方式,請參考 [C#.NE ...

  2. [Xamarin.Android] 如何透過電子郵件部署Xamarin.Android App (转帖)

    Android App在部署到實機的時候不像iOS的App限制你一定要使用向Apple申請的開發者憑證,在Apple不管是你要上架到Apple Store或者是企業內部署,你都必須向蘋果申請憑證. 而 ...

  3. [Testing] 測試電子原文書

    測試電子原文書 http://files.cnblogs.com/vincentmylee/SoftwareTesting2ndEdition.7z

  4. [Testing] 測試理論電子文件

    File path http://files.cnblogs.com/vincentmylee/TestTheory.7z

  5. X32位 天堂2 二章/三章 服务端协议号修改方法

    [本方法适合于2004-2006年之间天堂2由初章服务端修改至二章.三章端时协议号匹配问题]服务端版本位32位初章服务端 目前大部分SF用的协议号情况: 服务端是419 客户端是 417 419 42 ...

  6. 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...

  7. Universal Asynchronous Receiver/Transmitter

    USART簡介與特性 NRZ標準資料格式(Mark/Space) 半雙工/全雙工 Synchronous 同步傳輸 CLOCK SKEW Asynchronous 非同步傳輸 半/全雙工.同步/非同步 ...

  8. 集显也能硬件编码:Intel SDK && 各种音视频编解码学习详解

    http://blog.sina.com.cn/s/blog_4155bb1d0100soq9.html INTEL MEDIA SDK是INTEL推出的基于其内建显示核心的编解码技术,我们在播放高清 ...

  9. 我的Android进阶之旅------>Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

随机推荐

  1. CentOS下Redis安装与配置

    本文详细介绍redis单机单实例安装与配置,服务及开机自启动.如有不对的地方,欢迎大家拍砖o(∩_∩)o (以下配置基于CentOS release 6.5 Final, redis版本3.0.2 [ ...

  2. 转:The Great DOM Fuzz-off of 2017

    The Great DOM Fuzz-off of 2017 Posted by Ivan Fratric, Project Zero https://googleprojectzero.blogsp ...

  3. HDU 6182 A Math Problem

    暴力. $k$的$k$次方在$k=15$的时候,达到了最大不爆掉的情况. #include<bits/stdc++.h> using namespace std; long long an ...

  4. 洛谷P3834 [模板]可持久化线段树1(主席树) [主席树]

    题目传送门 可持久化线段树1(主席树) 题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定 ...

  5. 从Mybatis的视角去看Bean的初始化流程

    不涉及Spring完整的启动流程,仅仅从Mybatis的视角去分析几个关键的方法,找到Mybatis是如何通过这几个扩展点植入进去的,反过来看Spring是如何设计,埋下这些伏笔,实现其可扩展性. s ...

  6. 【交叉染色法判断二分图】Claw Decomposition UVA - 11396

    题目链接:https://cn.vjudge.net/contest/209473#problem/C 先谈一下二分图相关: 一个图是二分图的充分必要条件: 该图对应无向图的所有回路必定是偶环(构成该 ...

  7. C和指针之学习笔记(4)

    第9章 字符串 字符串的输入与输出 int  ch;  char strings[80];  FILE *input; (1)scanf(“%c”,&ch);   printf(“%c \n” ...

  8. POJ3450 Corporate Identity

    后缀数组. 解决多个字符串的最长公共子串. 采用对长度的二分,将子串按height分组,每次判断是否在每个字符串中都出现过. 复杂度O(NlogN) By:大奕哥 #include<cstrin ...

  9. [HDU1290]献给杭电五十周年校庆的礼物

    [HDU1290]献给杭电五十周年校庆的礼物 题目大意: 问\(n(n\le1000)\)个平面能够将一个三维空间分成几部分. 思路: 公式\(\frac{n^3+5n+6}6\). 源代码: #in ...

  10. 求n的阶乘 (python实现)

    描述 给定一个数n,范围为0≤n≤100,请你编程精确的求出n的阶乘n!. 输入 输入数据有多行,每行一个整数n,当n<0时输入结束. 输出 输出n的阶乘. 样例输入 1234-1 样例输出 1 ...