企业内常常需要构建一个PKI公钥体系(内部的,不需要外部信任的),用来对内部用户、应用、服务、设备等进行身份验证,或者对代码进行签名。然而没有硬件加密模块(HSM)的软实现CA均存在各种各样的安全问题。
亚马逊云科技Amazon Certificate Manager在大部分Region均提供了Private CA服务(中国区域目前没有提供),由于亚马逊云科技维护CA的私钥(类似于HSM),私钥时不会泄露,ACM PCA便可以用来构建安全的企业内PKI公钥体系。
本文主要使用CLI创建根CA (RootCA) 中级CA (Intermediate CA)以及一个终端实体证书(End-Entity Cert),通过这个过程大家可以了解PKI公钥体系是如何构成的。
需要注意的是:
- 为了简化,我们在此会采用S3公开访问的形式托管CRL,但是基于目前的最佳实践,在生产环境中我们仍然建议使用CloudFront + OAI的形式访问阻止S3公开访问的形式托管CRL;
- 一个Private CA月费是400美金,本例会创建两个CA以构成一个体系,这样在月租上就会有800美金的支出(万幸第一个月你可以减免一个CA的费用)。除此之外,你签发证书还有一个一次性费用,这个就比较少了,这部分具体可以参考https://aws.amazon.com/certificate-manager/pricing/。
首先我们来聊一聊我们将要创建的CA的层次结构。PCA支持最多五级的层次结构,良好的层次结构可以对每个CA做到精细控制,可以有更高的安全性。我们在本文中会使用两级CA,Root CA – Subordinate CA (通常也叫做Intermediate CA),则示意如下。
一般实践中我们并不会使用Root CA来给终端实体来签发证书,Root CA一般会用来签发其他CA。而Intermediate CA则用来批量签发终端实体证书。
所有证书(包含CA证书),都需要进行签名,不同的是Root CA是自签名的,而次一级的证书(或者CA证书)都需要上一级的CA来签名。按照这个思路,我们开始CA的构建过程。
1) 创建Root CA,我们首先创建Root CA配置文件,存储为rca_config.json
{
"KeyAlgorithm":"RSA_2048",
"SigningAlgorithm":"SHA256WITHRSA",
"Subject":{
"Country":"CN",
"Organization":"Xi'an Goldendata IT Co., Ltd.",
"OrganizationalUnit":"IT Dept.",
"State":"Shaanxi",
"Locality":"Xi'an",
"CommonName":"XA Goldendata Root CA"
}
}
然后执行
$ aws acm-pca create-certificate-authority \
--certificate-authority-configuration file://rca_config.json \
--certificate-authority-type "ROOT" \
--idempotency-token root-ca-demo
可以得到返回
{
"CertificateAuthorityArn": "arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161"
}
我们这时通过控制台看一看ACM的状态
可以发现,此时尚未对Root CA实施自签名,所以我们首先要拿到CSR证书请求
$ aws acm-pca get-certificate-authority-csr \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161 \
--output text > rca.csr
然后我们使用Root CA对该CSR签名,即自签名,由于是Root CA,我们一般会给比较久的有效期
$ aws acm-pca issue-certificate \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161 \
--csr fileb://rca.csr \
--signing-algorithm SHA256WITHRSA \
--template-arn arn:aws:acm-pca:::template/RootCACertificate/V1 \
--validity Value=3650,Type=DAYS
可以得到Root CA的证书
{
"CertificateArn": "arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161/certificate/2da5b4a6dfb0fef5ed8c38f3de015aae"
}
我们需要将这个证书导出
$ aws acm-pca get-certificate \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161 \
--certificate-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161/certificate/2da5b4a6dfb0fef5ed8c38f3de015aae \
--output text > rca_cert.pem
然后将这个证书导入(安装)到ACM
$ aws acm-pca import-certificate-authority-certificate \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161 \
--certificate fileb://rca_cert.pem
这时,我们再检查一下控制台,可以确认Root CA已经生效了,可以用来做下一步动作。
需要注意的是,Root CA并不需要CRL。
2) 创建Intermediate CA,本流程其实类似于Root CA的创建过程,我们依然是首先要创建Intermediate CA的配置文件
{
"KeyAlgorithm":"RSA_2048",
"SigningAlgorithm":"SHA256WITHRSA",
"Subject":{
"Country":"CN",
"Organization":"Xi'an Goldendata IT Co., Ltd.",
"OrganizationalUnit":"R&D",
"State":"Shaanxi",
"Locality":"Xi'an",
"CommonName":"XA Goldendata R&D CA"
}
}
不同的是,我们需要创建一个CRL配置文件,当进行证书有效性检查时,会对CRL做检查(对于S3桶及权限的部分,我们在此不做赘述,具体可以参考https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaCreateCa.html#s3-policies)
{
"CrlConfiguration":{
"Enabled":true,
"ExpirationInDays":7,
"S3BucketName":"pki-demo-sean"
}
}
如同之前备注的,生产环境中建议使用CloudFront+OAI的方式,我们在此为了简单,使用了默认(可公共读)
然后执行创建CA,我们目前创建的并不是Root CA,注意CA类型
$ aws acm-pca create-certificate-authority \
--certificate-authority-configuration file://ica_config.json \
--revocation-configuration file://ica_revoke.json \
--certificate-authority-type "SUBORDINATE" \
--idempotency-token ica-demo
得到CA返回
{
"CertificateAuthorityArn": "arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/9a526f96-f417-49dc-886a-a5e268e7ef4d"
}
同样获取CSR
aws acm-pca get-certificate-authority-csr \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/9a526f96-f417-49dc-886a-a5e268e7ef4d
--output text > ica.csr
这时要注意,我们要使用第一步创建的Root CA签发这个CA证书,同时证书模板要选用SubordinateCACertificate_PathLen0/V1,pathlen为0表示这个CA不能签发CA,只能签发终端实体
aws acm-pca issue-certificate \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161 \
--csr fileb://ica.csr \
--signing-algorithm SHA256WITHRSA \
--template-arn arn:aws:acm-pca:::template/SubordinateCACertificate_PathLen0/V1 \
--validity Value=1095,Type=DAYS
我们得到它的证书返回
{
"CertificateArn": "arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161/certificate/c0af427d7d48c7d756f688c26e6e8a4a"
}
同样获取证书,也要注意这个证书是Root CA签发的,对应的参数不要搞错
aws acm-pca get-certificate \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161 \
--certificate-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/235f40bc-427f-43fc-93e5-bb27c402e161/certificate/c0af427d7d48c7d756f688c26e6e8a4a \
--output text > ica_cert.pem
需要整理ica_cert.pem,删除Root CA的证书部分。
最后安装证书,这个证书将安装到Intermediate CA上
$ aws acm-pca import-certificate-authority-certificate \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/9a526f96-f417-49dc-886a-a5e268e7ef4d \
--certificate fileb://ica_cert.pem \
--certificate-chain fileb://rca_cert.pem
Root CA的证书做为证书链,在命令中引用。这时我们可以在控制台确认
顺带一提,当这个CA有效时,S3的桶也写入了一个测试文件,如图
我们也可以将这个CA证书的内容通过工具解码,有如下内容
到此,两级的CA已经搭建完成了,下一步我们将使用这个CA签发终端实体证书,如果你有一个内部门户网站,通过证书做双向验证无疑是最安全的方式之一。
3) 创建终端实体证书
类似于一切证书创建流程,我们首先需要创建私钥,然后需要根据具体的内容来创建对应的CSR,然后使用Intermediate CA签发证书。
$ openssl req -new -nodes -newkey rsa:2048 -keyout end_entity.key -out end_entity.csr \
-subj "/C=CN/ST=Shaanxi/L=Xi'an/O=Xi'an Goldendata IT Co., Ltd./OU=R&D/CN=Sean Chang/emailAddress=sean@jinshuju.net"
然后我们使用Intermediate CA来签发
aws acm-pca issue-certificate \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/9a526f96-f417-49dc-886a-a5e268e7ef4d \
--csr fileb://end_entity.csr \
--signing-algorithm SHA256WITHRSA \
--template-arn arn:aws:acm-pca:::template/EndEntityCertificate/V1 \
--validity Value=365,Type=DAYS
{
"CertificateArn": "arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/9a526f96-f417-49dc-886a-a5e268e7ef4d/certificate/3e5e4a71e0ba7c82238093fc1588a131"
}
获取证书
$ aws acm-pca get-certificate \
--certificate-authority-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/9a526f96-f417-49dc-886a-a5e268e7ef4d \
--certificate-arn arn:aws:acm-pca:ap-east-1:xxxxxx:certificate-authority/9a526f96-f417-49dc-886a-a5e268e7ef4d/certificate/3e5e4a71e0ba7c82238093fc1588a131 \
--output text > end_entity.pem
然后我们合成p12文件
$ openssl pkcs12 -export -in end_entity.pem -inkey end-entity.key -out certificate.pfx -certfile ica_cert.pem
我们尝试在终端上打开,可以有以下截图
同时我们可以注意到,证书中也包含了CRL列表,以供确认证书是否被吊销。
总结
需要注意的是,现阶段ACM PCA只是一个CA的管理工具,其本身并不会展示签发的证书列表(这个和ACM证书管理的功能不同),所以当你想查看签发记录或者吊销证书时,你需要
1) 生成审计报告,报告中会列出CA所签发的证书,生成的报告会存储在S3中,生成过程可以通过控制台或者CLI
2) 通过命令行吊销证书,参数是证书序号,这个可以参考https://docs.aws.amazon.com/cli/latest/reference/acm-pca/revoke-certificate.html
希望本文的流程拆解可以帮助你更好的了解PKI以及PCA。