windows下的证书

数字证书本身就不用过多的解释了,参见维基百科

数字证书最常用的格式标准是X.509。windows上也是使用的X.509。

常见的文件格式

  • der

der的全写是Distinguished Encoding Rules(唯一编码规则),是ASN.1标准中定义的一种二进制编码方式。

  • pem

pem的全写是Privacy-Enhanced Mail(隐私增强型电子邮件格式),主要在RFC 1422定义。为了方便der通过电子邮件传输,采用了base64编码。

pem格式并不约束存放的内容,也可以用来存放私钥、根证书甚至证书签名请求(比如这里)。

可以从注释中看出里面保存的是什么内容:

1
2
-----BEGIN {TYPE}-----
-----END {TYPE}-----

列几个常见的TYPE

  1. RSA PRIVATE KEY
  2. PRIVATE KEY
  3. PUBLIC KEY
  4. NEW CERTIFICATE REQUEST
  • pfx

pfx的全写是Personal Information Exchange,是微软的个人信息交换文件格式。

因为太过复杂而被诟病,后被RSA实验室提出的PKCS #12替代。

  • PKCS #12

PKCS #12是公钥密码学标准中的个人消息交换标准,用于实现存储许多加密对象在一个单独的文件中。通常用它来打包一个私钥及有关的X.509证书,或者打包信任链的全部项目。

  • PKCS #7

PKCS #7是公钥密码学标准中的密码消息语法标准,在RFC 2315中定义。规范了以公开密钥基础设施(PKI)所产生之签名/密文之格式。其目的一样是为了拓展数字证书的应用,其中,包含了S/MIMECMS

java天生支持PKCS #7,通常使用.keystore扩展名。

常见的扩展名

  • .der

使用der标准编码的二进制文件。

  • .pem

通常就是base64编码的der。需要结合文件名来判断存放的内容。比如cert.pem一般是公钥,key.pem是私钥。

  • .key

pem格式的私钥。

  • .cer, .crt

通常是pem格式的公钥。有时候也可能是der格式的公钥。

  • .pfx

保留了微软pfx格式的扩展名,但通常使用的是PKCS #12格式。

  • .keystore, .p7b

PKCS #7格式的文件。其中,java天生支持.keystore。

windows下的证书工具

certmgr.msc(证书管理单元)

注意区分certmgr.msc和certmgr.exe

certmgr.msc会打开当前用户的证书。它属于mmc(Microsoft管理控制台)的一部分。

mmc.exe(Microsoft管理控制台)

进入mmc后,需要先添加证书管理单元。

在添加时,需要选择证书管理单元的管理账户。分为我的用户账户、服务账户和计算机账户。

如果选择我的用户账户,即和certmgr.msc完全一致。

certmgr.exe(证书管理器工具)

certmgr.exe在安装Visual Studio时会被顺带安装。它的路径通常在C:\Program Files (x86)\Windows Kits\10\bin\{Version}\x64\certmgr.exe,无运行依赖,可以单独拷贝至其它电脑上运行。

它可以用来将证书添加到受信任的发布者
使用管理员权限运行:

1
certmgr.exe -add ExcelAddin_ProdKey.cer -c -s -r localMachine TrustedPublisher

即可将公钥添加到受信任的发布者。

注意,如果是自签证书,需要同时添加根证书

1
certmgr.exe -add ExcelAddin_ProdKey.cer -c -s -r localMachine Root

ExcelAddin_ProdKey.cer可为der格式也可为pem格式,certmgr.exe都支持。

Powershell Cmdlet

Powershell提供了很多证书相关的Cmdlet,如

来实现新建证书、导出证书、获取证书信息等等。

openssl

openssl就不用多说啦,最通用的证书工具。

证书操作

创建自签证书

首先生成自签名证书,保存在windows证书存储区里。

1
2
3
4
5
6
7
$cert = New-SelfSignedCertificate `
-Type Custom `
-Subject "CN=Tasty Pub" `
-CertStoreLocation Cert:\CurrentUser\My `
-KeyUsage DigitalSignature `
-KeyAlgorithm RSA -KeyLength 2048 `
-NotAfter (Get-Date).AddMonths(36)

然后将证书导出成pfx文件。

1
2
3
4
5
6
7
8
9
10
11
$password = "yourpassword"
$securePassword = ConvertTo-SecureString -String $password -Force -AsPlainText
# 如果担心忘记密码,也可以将密码设成空:
$emptyPassword = New-Object System.Security.SecureString
$outname = "./tastypub.pfx"
Export-PfxCertificate `
-Cert $cert `
-FilePath $outname `
-Password $emptyPassword `
-ChainOption EndEntityCertOnly `
-NoProperties -Verbose

从pfx里导出cer公钥

想要从pfx里导出cer公钥,可直接使用Export-Certificate:

1
2
Get-PfxCertificate -FilePath ExcelAddin_ProdKey.pfx | 
Export-Certificate -FilePath ExcelAddin_ProdKey.cer -Type CERT

注意这里Export-Certificate导出的是der格式。

也可使用openssl

1
openssl pkcs12 -in ExcelAddin_ProdKey.pfx -out ExcelAddin_ProdKey.crt -nokeys -clcerts

openssl默认导出的是pem格式。

der和pem可以用openssl任意转换

1
2
3
openssl x509 -inform der -in ExcelAddin_ProdKey.cer -out ExcelAddin_ProdKey.1.pem
openssl x509 -outform der -in ExcelAddin_ProdKey.1.pem -out ExcelAddin_ProdKey.1.cer
fc.exe ExcelAddin_ProdKey.cer ExcelAddin_ProdKey.1.cer

通过openssl创建自签证书

也可以通过openssl生成pfx。

首先要确认openssl.cnf是否存在,为了统一,我们直接创建一个:

1
Invoke-WebRequest 'http://web.mit.edu/crypto/openssl.cnf' -OutFile ./openssl.cnf

首先使用openssl-req生成一个私钥和公钥:

1
2
3
4
5
6
7
8
openssl req `
-config "./openssl.cnf" `
-x509 -newkey rsa:4096 `
-nodes `
-keyout ExcelAddin_New.key `
-out ExcelAddin_New.crt `
-days 1080 `
-subj /CN="Tasty Pub"

然后使用openssl-pkcs12基于私钥和公钥生成pfx:

1
2
3
4
5
6
7
8
$password = "yourpassword"
$emptyPassword = ""
openssl pkcs12 `
-export `
-out ExcelAddin_New.pfx `
-inkey ExcelAddin_New.key `
-in ExcelAddin_New.crt `
-password pass:$emptyPassword