作为文件形式存在的证书一般有这几种格式:
1.带有私钥的证书
由Public Key Cryptography Standards
#12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形式,以pfx作为证书文件后缀名。
2.二进制编码的证书
证书中没有私钥,DER 编码二进制格式的证书文件,以cer作为证书文件后缀名。
3.Base64编码的证书
证书中没有私钥,BASE64 编码格式的证书文件,也是以cer作为证书文件后缀名。
由定义可以看出,只有pfx格式的数字证书是包含有私钥的,cer格式的数字证书里面只有公钥没有私钥。
在pfx证书的导入过程中有一项是“标志此密钥是可导出的。这将您在稍候备份或传输密钥”。一般是不选中的,如果选中,别人就有机会备份你的密钥了。如果是不选中,其实密钥也导入了,只是不能再次被导出。这就保证了密钥的安全。
如果导入过程中没有选中这一项,做证书备份时“导出私钥”这一项是灰色的,不能选。只能导出cer格式的公钥。如果导入时选中该项,则在导出时“导出私钥”这一项就是可选的。
如 果要导出私钥(pfx),是需要输入密码的,这个密码就是对私钥再次加密,这样就保证了私钥的安全,别人即使拿到了你的证书备份(pfx),不知道加密私 钥的密码,也是无法导入证书的。相反,如果只是导入导出cer格式的证书,是不会提示你输入密码的。因为公钥一般来说是对外公开的,不用加密
pvk确实是指私钥的信息。通常在你申请证书的时候这个私钥的信息是保存在单个的文件.pvk中,当然你也可以保存在cer文件中(一般是密码保护的)。
makecert -r -n "CN=Enterprise Name" -b 01/01/2009 -e 01/01/2011 -sv TestPrj.pvk TestPrj.cer
cert2spc TestPrj.cer TestPrj.spc
pvkimprt -pfx TestPrj.spc TestPrj.pvk
pvk2pfx -pvk TestPrj.pvk -spc TestPrj.spc -pfx TestPrj.pfx
证书创建工具 (Makecert.exe)
http://msdn.microsoft.com/zh-cn/library/bfsktky3(VS.80).aspx
Cert2spc.exe(软件发行者证书测试工具)
http://msdn.microsoft.com/zh-cn/library/f657tk8f.aspx
Signcode.exe(文件签名工具)
http://msdn.microsoft.com/zh-cn/library/9sh96ycy.aspx
强名称工具 (Sn.exe)
http://msdn.microsoft.com/zh-cn/library/k5b5tt23(VS.80).aspx
pvk2pfx
http://msdn.microsoft.com/zh-cn/library/bb384246.aspx
===
用户通过网站在线申请代码签名证书时会生成证书私钥文件,如:myCert.pvk 并保存到浏览器中,而代码签名证书成功颁发后的证书文件为公钥文件,如:myCert.spc,是一个文本文件。又称:软件发行证书(Software Publishing Certificate)。代码签名证书一般都是采用公钥和私钥分离的两个文件方式,适合于 DOS 命令行方式的代码签名。如果您您希望把代码签名证书导入到Windows证书存储区中。可以通过技术手段进行合并成一个单文件。
===
一、证书创建工具(Makecert.exe)
二、证书管理器工具 (Certmgr.exe)
证书管理器工具管理证书、证书信任列表 (CTL) 和证书吊销列表 (CRL)。
启动:
a) “开始”——“运行”——输入certmgr.msc
b) 打开IE浏览器,工具——IE选项——内容——证书
或者 “开始”——“运行”——输入Certmgr
c) 使用MMC管理 (Microsoft Management Console)
三、创建发行者证书工具 (Cert2spc.exe)
发行者证书测试工具通过一个或多个 X.509 证书创建发行者证书 (SPC)。Cert2spc.exe 仅用于测试目的。可以从证书颁发机构(如 VeriSign 或 Thawte)获得有效的 SPC。
格式:cert2spc cert1.cer [cert2.cer … certN.cer] outputSPCfile.spc
certN.cer 要包含在 SPC 文件中的 X.509 证书的名称。可以指定多个以空格分隔的名称。
outputSPCfile.spc 将要包含 X.509 证书的 PKCS #7 对象的名称。可以使用 .spc 文件作为文件签名工具 (Signcode.exe) 的输入。
例子:下面的命令从 myCertificate.cer 创建一个 SPC 并将其放入 mySPCFile.spc。
cert2spc myCertificate.cer mySPCFile.spc
四、创建个人信息交换证书工具(Pvk2pfx.exe)
Pvk2Pfx命令行工具是用于将包含在 .spc,.cer 和 .pvk 文件中的公钥和私钥复制到个人信息交换(.pfx)文件中。
个人信息交换格式证书是唯一可用于导出证书及其私钥的文件格式。
格式:pvk2pfx /pvk pvkfilename.pvk [/pi pvkpassword]
/spc spcfilename.ext [/pfx pfxfilename.pfx [/po pfxpassword] [/f] ]
/pvk pvkfilename.pvk |
指定私钥文件(.pvk)的文件名。 |
/spc spcfilename.ext |
指定软件发行者证书(Software Publisher Certificate (SPC))的文件名和扩展名。这个证书文件既可以是 .spc 文件又可以是 .cer 文件。 |
/pfx pfxfilename.pfx |
为生成的.pfx指定文件名。 |
/Pi pvkpassword |
指定.pvk私钥文件的密码。 |
/po pfxpassword |
为生成的.pfx指定密码,如果没有指定,则.pfx的密码取.pvk的密码。 |
/f |
配置覆盖开关。当存在与要生成的 .pfx 相同文件名的 .pfx文件时,是否进行覆盖 |
1、 生成证书、分发证书
证书使用前面“使用makecert工具获得”章节生成的MyTestCert,当然也可以是从商业CA获得的证书。
你获得的证书应该是含有公钥和私钥的完整证书,一般是pfx形式的证书。
要接收加密数据,需要把你的公钥分发给加密数据的加密方,加密方使用你的公钥加密数据。
证书要么以pfx形式存在,要么被导入到证书存储区。
如果你的证书存在于证书存储区可以通过证书管理控制台提供的证书导出功能导出只含有公钥的cer证书。
如果证书以pfx证书文件形式存在,可以通过代码读取证书然后导出为只含公钥的cer证书。
参考前面章节导出一个名为MyTestCert.cer证书,将此证书分发给需要用来加密的加密方。
2、 字符串明文转成某一代码页对应的编码字节流
待加密的数据可能有两种形式,一种是二进制的数据,本身就是一组字节流,这样的数据可以跳过这一步,直接进入加密步骤。还有一种情况是字符串数据,字符串中同样的字符使用不同的代码页会生成不同的字节码,所以从字符串到字节流的转换是需要指定使用何种编码的。在解密之后,要从字节流转换到字符串就要使用相同的代码页解码,否则就会出现乱码。
//保存明文文件的字节数组
Byte[] plainTextByte = Encoding.UTF8.GetBytes(“RSA证书对敏感数据进行加密!”);
这里用utf8代码页对明文进行编码,把明文字符串转成字节流。
3、 加密操作
//从只包含公钥的证书文件载入证书
X509Certificate2 myX509Certificate2 = newX509Certificate2(@"C:SamplesPartnerAEncryptMsgMyTestCert.cer");
//从cer证书中获得含公钥的RSACryptoServiceProvider
RSACryptoServiceProvider myRSACryptoServiceProvider = (RSACryptoServiceProvider)myX509Certificate2.PublicKey.Key;
//使用RSACryptoServiceProvider把明文字节流加密为密文字节流
Byte[] Cryptograph = myRSACryptoServiceProvider.Encrypt(plainTextByte, false);
使用1024为的密钥加密,原料应该是128字节(1024位)的byte[]的原始数据,加密后的数据也是128字节(1024位),如果明文不足128字节,RSACryptoServiceProvider会自动用随机数补足128字节。
Dotnet的RSA实现有个特点,它必须要在明文中添加一些随机数,所以明文不能把128字节占满,实际测试,明文最多为117字节,留下的空间用来填充随机数。
所以,用同一个密钥对同一串字符串进行加密,每次得到的密文都是不一样的。
4、 解密操作
//从证书文件载入证书,如果含有私钥的,需要提供保存证书时设置的密码
X509Certificate2 myX509Certificate2 = newX509Certificate2(@"C:SamplesPartnerAEncryptMsgMyTestCert.pfx", "password");
//从证书中获得含私钥的RSACryptoServiceProvider
RSACryptoServiceProvider myRSACryptoServiceProvider = (RSACryptoServiceProvider)myX509Certificate2.PrivateKey;
//使用RSACryptoServiceProvider把密文字节流解密为明文字节流
byte[] plaintextByte = myRSACryptoServiceProvider.Decrypt(Cryptograph, false);
解密需要载入含私钥的pfx证书,需要提供私钥保护密码。
5、 从编码字节流转成字符串明文
使用加密时采用的同样的代码页utf8把解密后的明文byte[]转成字符串
string Plaintext = Encoding.UTF8.GetString(plaintextByte);