我有一个C#单元测试项目,我想测试一些我写过的加密扩展。我想使用虚拟证书进行测试,但我有以下限制:
.pfx
文件)包含在git存储库或构建中,因为这样做会违反安全协议。因此,我无法从项目中包含的文件中读取证书。由于我要进行加密和解密,我需要拥有私钥信息。如何在这些限制内以编程方式创建此证书?
答案 0 :(得分:3)
执行此操作的一种方法是创建用于测试的证书,将其转换为基本64字符串,然后在代码中从此字符串中读取证书。这需要四个步骤:
<强> 1。创建.cer和.pvk文件
要执行此操作,可以使用MakeCert.exe
工具(请注意this tool is deprecated,Microsoft建议您使用New-SelfSignedCertificate PowerShell cmdlet。我还没试过这个,但可能是任何一种方法都可行。)这是一个.NET Framework工具,作为Windows SDK的一部分包含在内。我碰巧在我的机器上安装了Windows 7 SDK,所以对我来说这个exe位于C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\
下,但结果可能会有所不同。这个工具完全符合我们的要求!来自documentation:
证书创建工具生成X.509证书仅用于测试目的。它为数字签名创建公钥和私钥对,并将其存储在证书文件中。此工具还会将密钥对与指定的发布者名称相关联,并创建一个X.509证书,该证书将用户指定的名称绑定到密钥对的公共部分。
为了这个例子,让我们调用证书TestCert
。要创建.cer和.pvk文件,请运行以下命令:
MakeCert.exe -sv TestCert.pvk -n "cn=Test Certificate" TestCert.cer -r
-sv
标志表示要创建的.pvk文件的名称,-n
标志是我们证书的X.500兼容名称(它最容易使用< em>&#34; cn = CertName&#34; 格式如上所述),-r
标志表示它将自签名。如果要指定证书的开始日期和结束日期,请使用-b
和-e
标记,并将日期格式设置为mm/dd/yyyy
(默认情况下,证书从当天开始有效创作直到2039年)。如果您的证书将用于加密和解密(如我的),则必须指定-sky Exchange
和-pe
标志。在此过程中,系统会提示您为证书创建密码。
<强> 2。创建.pfx文件
这可以使用pvk2pfx.exe
工具完成,该工具应与MakeCert.exe
位于同一位置。此工具将.pvk和.cer文件转换为.pfx文件。要使用此工具,请运行以下命令:
pvk2pfx.exe -pvk TestCert.pvk -spc TestCert.cer -pfx TestCert.pfx
-pvk
标志是要使用的.pvk文件的文件名(在步骤1中创建),-csp
标志是要使用的.cer文件的文件名(在步骤中创建) 1),-pfx
标志是将要创建的.pfx文件的名称。在此过程中,系统会提示您输入在步骤1中创建的密码。
第3。获取.pfx文件的基本64字符串表示
这非常简单,可以使用Get-Content
Powershell cmdlet和System.Convert.ToBase64String
方法完成。为此,打开Powershell窗口并运行以下命令:
$content = Get-Content TestCert.pfx -Encoding Byte
[System.Convert]::ToBase64String($content) | Out-File "TestCert.txt"
现在我们在TestCert.txt中为.pfx文件提供了基本64字符串。
<强> 4。以编程方式创建证书
现在我们可以在代码中创建证书,如下所示:
namespace MyTests
{
using System;
using System.Security.Cryptography.X509Certificates;
public class MyTests
{
// Copy and paste the string from TestCert.txt here.
private const string CertText = "<text>";
// Use the password you created in steps 1 and 2 here.
private const string Password = "p4ssw0rd";
// Create the certificate object.
private readonly X509Certificate2 TestCert = new X509Certificate2(
Convert.FromBase64String(MyTests.CertText),
MyTests.Password);
}
}