是个大坑,留作备用
Adding custom embedded Precertificate SCTs into the certificate?
Asked 5 years, 6 months ago
Modified 5 years, 6 months ago
Viewed 766 times
1
It it possible to insert a list of ct certificate timestamps in the my own certificate created in by internal CA using openssl configuration file. I didnt find any information about ASN.1 sequence describing how to insert SCTs extension into openssl.cnf file.
For example:
CT Precertificate SCTs:
Signed Certificate Timestamp:
Version : v1(0)
Log ID : A4:B9:09:90:B4:18:58:14:87:BB:13:A2:CC:67:70:0A:
3C:35:98:04:F9:1B:DF:B8:E3:77:CD:0E:C8:0D:DC:10
Timestamp : Nov 13 16:57:03.632 2014 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:45:02:20:06:14:6A:E3:6D:0F:84:5D:6A:98:E7:29:
94:80:8B:F2:A4:23:85:68:4E:F9:BC:50:7C:FF:7B:94:
EB:20:54:82:02:21:00:91:63:83:FD:F6:31:5E:38:08:
AF:A7:5E:00:B7:0B:9B:1F:8B:FD:4D:7E:49:3C:43:E6:
64:E5:4B:F9:60:D7:89
Signed Certificate Timestamp:
Version : v1(0)
Log ID : 68:F6:98:F8:1F:64:82:BE:3A:8C:EE:B9:28:1D:4C:FC:
71:51:5D:67:93:D4:44:D1:0A:67:AC:BB:4F:4F:FB:C4
Timestamp : Nov 13 16:57:03.619 2014 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:45:02:20:61:4F:69:89:80:6A:62:2D:8E:A2:D0:24:
A5:E2:1D:74:67:51:77:C1:9B:DE:99:DE:16:56:2B:02:
77:A8:25:49:02:21:00:D3:41:6C:5D:88:40:F0:7A:FE:
E0:25:09:86:71:63:86:49:54:DD:96:E4:B5:9B:4A:84:
65:A9:25:12:F1:B7:E0
Is it possible at all?
certificatesopenssltimestamp
Share
Improve this question
Follow
asked Jul 5, 2017 at 20:19
Marko Farkas’s user avatar
Marko Farkas
1111 bronze badge
1
See the man page for x509v3_config on your system or on the web under the heading ‘Arbitrary Extensions’ and its link to ASN1_generate_nconf. It’s too much like work for me write out a full answer 🙁 –
dave_thompson_085
Jul 6, 2017 at 4:21
Add a comment
1 Answer
Sorted by:
Highest score (default)
2
RFC 6962 describes (pretty hidden) that:
by encoding the SignedCertificateTimestampList structure as an ASN.1 OCTET STRING and inserting the resulting data in the TBSCertificate as an X.509v3 certificate extension (OID 1.3.6.1.4.1.11129.2.4.2).
(OID-ref here.)
Share
Improve this answer
Follow
edited Oct 7, 2021 at 7:59
Community’s user avatar
CommunityBot
1
answered Jul 5, 2017 at 22:30
eckes’s user avatar
eckes
96288 silver badges1919 bronze badges
Although that top-level structure (OID + OCTET STRING) is the same for all extensions and OpenSSL does it automatically; the harder part is the structure inside the OCTET STRING. –
dave_thompson_085
Jul 6, 2017 at 4:22
@dave_thompson_085: RFC writes "SerializedSCT" is an opaque byte string that contains the serialized TLS structure — whatever that means. Found a good breakdown on the "Pierky" blog. –
StackzOfZtuff
Jul 6, 2017 at 11:34
The structure of SignedCertificateTimestamoList is described in the RFC, it seems you even quoted them in the question. –
eckes
Jul 7, 2017 at 10:37
How to create and embed Signed Certificate Timestamp (SCT) in certificate
Asked 4 months ago
Modified 3 months ago
Viewed 194 times
1
I have deployed a Certificate Transparency (CT) log server that uses Google’s CTFE (named "certificate-transparency-go" on Github) and Trillian Projects. And I have issued a pre-certificate, submitted to my own CT log server.
I have this text information from the server (some information has been removed):
Uploading pre-certificate to log
Uploaded chain of 4 certs to V1 log at http://
LogID: 400cb51cb037bad42****ba4b12e073
LeafHash: 376da8b2be20b0426d5e*8fa00d78b9e570cc5a88af0490e9e2
Signature: Signature: Hash=SHA256 Sign=ECDSA Value=304502206419ae26edf93a***032022100b8353a9a49d0b12*****e521fd21dfabd17969d8fc17302421
But I have not found the solution to embed this information in a X.509 Certificate Extension (OID is "1.3.6.1.4.1.11129.2.4.2"). As far as I know, this information should be encoded as HEX OCTET_STRING, but I don’t know what I should do to make it work.
For now, my own CT log server is not trusted, but I still want to add it to my certificate.
Note that I’m using a private PKI, so Mozilla, Apple and Microsoft will not trust my root certificate.
certificatespublic-key-infrastructurecertificate-authorityx.509certificate-transparency
Share
Improve this question
Follow
edited Aug 22, 2022 at 12:31
Shireheart’s user avatar
Shireheart
35011 silver badge77 bronze badges
asked Aug 22, 2022 at 10:51
Levi Marvin’s user avatar
Levi Marvin
1344 bronze badges
Add a comment
1 Answer
Sorted by:
Highest score (default)
0
All X.509v3 extension values are encoded outermost as OCTET STRING — that’s in the syntax definition — which contains a DER encoding usually of an ASN.1 structure; but (v1) SCTList in RFC6962 is encoded using the TLS-formerly-SSL forms defined in e.g. RFC5246 section 4 applied to the list structure shown in 3.3, whose element(s) is(are) the SignedCertificateTimestamp structure shown on the same page just above that link, and thus needs to be wrapped in an extra layer of OCTET STRING.
As an example, https://stackoverflow.com/questions/69205710/modifying-extension-list-in-x509-certificate-using-openssl-in-c inserts an SCTList extension into a cert using OpenSSL — after deleting the poison extension of the precert, which is irrelevant here. It uses a (correctly) pre-encoded value for the SCTList extension provided by the OP, which when de-base64-ed and displayed in hex for humans, breaks down as follows:
04 81 7a 00 78 00 76 00 b0 cc 83 e5 a5 f9 7d 6b
af 7c 09 cc 28 49 04 87 2a c7 e8 8b 13 2c 63 50
b7 c6 fd 26 e1 6c 6c 77 00 00 01 66 7b cf f0 d0
00 00 04 03 00 47 30 45 02 21 00 ca 24 f3 d0 85
6a a3 7b 5a d0 ab e4 f4 eb 1d 22 36 52 d3 ee b5
fb d6 4d b7 54 f6 64 86 6f d0 0b 02 20 7e 1c 0d
2b b8 b3 7a ad 1f 1c 09 6e ec 7b 98 46 39 af ca
6e 75 45 17 65 35 68 5d e7 42 d0 76 ee
04 81 7a DER header for ‘extra’ OCTET STRING containing 0x7a bytes
00 78 length of SCTList
00 76 length of only SCT entry in list — in real use the CA would get SCTs from multiple logs and put them all into one list, but you have only one DIY log so like OP you would only have one entry
00 version
b0 cc 83 e5 a5 f9 7d 6b af 7c 09 cc 28 49 04 87 2a c7 e8 8b 13 2c 63 50 b7 c6 fd 26 e1 6c 6c 77 logid
00 00 01 66 7b cf f0 d0 timestamp
00 00 length of extensions — if nonzero would be followed by actual extension data
04 03 SignatureAndHashAlgorithm from RFC5246 for SHA256-with-ECDSA (note RFCs 8422 and 8446 changed TLS to a single combined scheme rather than independent hash and ‘pure’ signature components, but AFAICT that isn’t applied to CT)
00 47 length of signature 30 45 02 21 … 02 20 … ECDSA signature in ASN.1 DER encoding (SEQUENCE of two INTEGERs) specified in RFC3279 — note for a 256-bit curve this will normally vary in the range 70-72 (0x46-0x48) bytes but will sometimes (rarely) be shorter
What form(s) of this information you need to give your CA software, in particular whether part(s) or all of this must be in hex, are up to your software, which you didn’t identify or describe.
ADDED: You say you are using XCA; I assume you mean this which is a GUI for OpenSSL, and per this manual page accepts additional extensions in the same format as an OpenSSL config file (for req or x509 or ca). The "text" information in your Q is mostly textual representations of data that is not actually textual: you have the timestamp as decimal and in a display form, which you must convert; the logid in hex (apparently, though you mangled it) (and also the leaf hash, which you don’t need), and the signature mostly in hex (ditto) plus the two algorithm names. And it happens your signature is the same length as my example from the other Q (0x47=71 bytes) so for this instance you can use the same length fields I showed (but for other log entries = precerts you will often have to change them). Also your sigalg is the same as my example; that is more likely to remain true because AFAICT most logs now use ECDSA-SHA256, although other algorithms are permitted. Thus:
go to the ‘advanced’ tab of cert (or CSR) input, click edit
enter ct_precert_scts=DER:
enter (in order) the pieces I put in fixed-on-blue format above EXCEPT replace my logid with yours (in hex and NOT mangled), my timestamp with 182c4788384 (which is yours converted to hex), and my signature data with yours (ditto, keeping the prefix length); but don’t put spaces between the hexit-pairs as I used for display, instead either replace by colon or delete. You may prefer to prepare this in some other tool like notepad and then copy&paste; if so you can combine #2 into this
click validate
Also you might want to know there is a new v2 spec as of last year — I have no clue whether, when and how it will be supported by the software you’re using, but it uses data that is basically equivalent in concept but different in a number of details.
Share
Improve this answer
Follow
edited Oct 14, 2022 at 5:53
answered Aug 23, 2022 at 20:21
dave_thompson_085’s user avatar
dave_thompson_085
9,94411 gold badge2525 silver badges2828 bronze badges
Thanks for you help! I’m sorry about I have not provide more information. I used OpenSSL to generate certificate, So I have to add these information to config file of OpenSSL. Do you know how to do that? –
Levi Marvin
Aug 25, 2022 at 5:03
I’m using the CA software named XCA is based OpenSSL, so if I want to add the SCT List extension, I need to write it be the format that supported by OpenSSL config. –
Levi Marvin
Aug 25, 2022 at 5:07
Levi: If you are or it is using commandline openssl, the config for that doesn’t support SCTList; it does support arbitrary ASN.1 structures but not TLS ones, so you must put the entire encoding in hex (as you guessed), like (given 1.0.2 up) ct_precert_scts=DER:04817a0078007600b0cc83e5a5f97d6b…. If using library need much more details to answer. –
dave_thompson_085
Aug 29, 2022 at 1:51
dave_thompson_085: Hello Dave, Is there any way that I can encoding SCT Information to HEX? I just have the text SCT information. –
Levi Marvin
Sep 17, 2022 at 12:23
Levi: If your text information is sufficient to construct the binary structure defined in the RFC and shown in the example I cited and quoted, converting to hex is trivial. Otherwise no. –
dave_thompson_085
Sep 20, 2022 at 6:30
Show 3 more comments
公钥基础设施的搭建与维护(基于 OpenSSL)
2022年4月24日 284点热度 3人点赞 0条评论
公钥基础设施的搭建与维护(基于 OpenSSL)
本文为未经允许严禁转载,违者将被追究法律责任!
最后更新:2022/04/08
最后校对:2022/04/08
本文基于环境:
操作系统:Windows 11 Professional Workstation 22581
OpenSSL:OpenSSL 1.1.1n
阅读本文前须知:
本文中不包含对 OpenSSL 配置文件的介绍;
文章目录仅作分类,不保证可以正确跳转;
关于“主题信息”和“主体信息”,前者包含于后者;
除“公钥基础设施搭建与技术细节”外,所有地方的代码仅作示例,如需使用请根据需求修改;
文中所述“软件”均包含操作系统。
为防止漏洞攻击,请所有使用 OpenSSL 1.1 版本的用户将版本升级至 1.1.1n
为防止漏洞攻击,请所有使用 OpenSSL 3.0 版本的用户将版本升级至 3.0.2
目录
目录
基础知识
2.1. 概论
2.1.1. 数字证书
2.1.2. 证书吊销列表
2.1.3. OID
2.2. 证书颁发机构
2.2.1. 根证书颁发机构证书
2.2.2. 扩展验证的证书
2.3. 证书注册审批机构
2.4. 签名证书时间戳
数字证书与扩展
3.1. 密钥标识符
3.1.1. 授权密钥标识符
3.1.2. 主体密钥标识符
3.2. 授权信息访问
3.2.1. 联机证书状态协议
3.2.2. 证书颁发机构颁发者
3.3. CRL 分发点
3.4. 增强型密钥用法
3.5. 主体可选名称
3.6. SCT 列表
3.7. “基本约束”与“密钥用法”
3.8. 证书策略
搭建与技术细节
4.1. 证书颁发机构
4.1.1. 基本要求
4.1.2. 数字证书
4.2. 证书注册审批机构
维护与审计基础知识
2.1. 概论
公钥基础设施(Public Key Infrastructure)简称“PKI”。公钥基础设施是用于提供可信服务、数字证书,管理公钥加密的软硬件、结构与角色的集合。
公钥基础设施包括:证书颁发机构(Certificate Authority)、证书注册审批机构(Registration Authority)。
大多数可以提供可信服务和数字证书的实体均有其自己的完整的公钥基础设施。
2.1.1. 数字证书
数字证书(Digital Certificate)简称“证书”。数字证书为符合 X.509 格式,ASN.1 表示方法,IETF 标准与 RFC 文件规定的数据。数字证书分为不同版本,截至目前共有三个版本(版本 1、版本 2、版本 3)。
其结构如下:
数字证书
基本部分
版本
序列号
签名及算法标识符
颁发者主题信息
有效期
开始日期
结束日期
使用者主题信息
公钥及算法标识符
颁发者唯一标识符(自版本 2 起)
使用者唯一标识符(自版本 2 起)
扩展部分(自版本 3 起)
基本约束
密钥用法
(其他扩展)
目前非特别老旧的操作系统均支持 V3 版本证书,绝大多数的常见证书为 V3 版本证书。
扩展部分可以添加除了标准、规范定义的扩展外的自定义扩展。扩展部分中的扩展使用 OID 定义。
证书扩展部分中所有的扩展在技术层面上均可以设置为关键扩展,关键扩展的作用为告知处理证书的软件这个扩展的信息必须被加载和处理。通常,处理关键扩展信息的方法内置于软件代码中,正因如此,除非关键扩展为规范定义的已知扩展,否则软件无法处理扩展并会将错误信息返回给用户。证书中的一些扩展必须设置为关键扩展。
图片(Windows 下的数字证书)
2.1.2. 证书吊销列表
证书吊销列表(Certificate Revokation List)简称“CRL”。其与可信列表一样同属于列表,但可信列表可能包含证书吊销列表,可将证书吊销列表理解为“不可信列表”。证书吊销列表与证书颁发机构证书一一对应,由证书颁发机构签发。证书吊销列表中存放有被吊销的证书信息,软件会从中检查这些信息来识别无效的证书。
证书吊销列表为符合 X.509 格式,ASN.1 表示方法,IETF 标准与 RFC 文件规定的数据。证书吊销列表也分为不同的版本,截至目前共有二个版本(版本 1、版本 2)。
其结构如下:
证书吊销列表
基本部分
版本
颁发者主题信息
有效期
生效日期
下一次更新日期
签名及算法标识符
扩展部分
授权密钥标识符
CRL 数字
(其他扩展)
证书吊销列表扩展部分中所有的扩展在技术层面上均可以设置为关键扩展,关键扩展的作用为告知处理证书吊销列表的软件这个扩展的信息必须被加载和处理。通常,处理关键扩展信息的方法内置于软件代码中,正因如此,除非关键扩展为规范定义的已知扩展,否则软件无法处理扩展并会将错误信息返回给用户。证书中的一些扩展必须设置为关键扩展。
由于证书吊销列表的数据大小与证书颁发机构吊销的证书数量成正相关,随着时间推移会放大传输证书吊销列表所需要的带宽和成本,因此 Google 积极推行 OCSP 协议来验证证书、证书链。
但现在的证书颁发机构更多采用“多证书吊销列表”或增量型证书吊销列表,前者被更多的采用。增量型证书吊销列表可以作为现有证书吊销列表的扩充,由证书吊销列表中的扩展指定。证书颁发机构在颁发证书时,可以预先将增量型证书吊销列表内置与证书中。需要吊销证书时,直接发布增量型证书吊销列表。但也可以将证书颁发机构颁发的证书进行划分,让某一时间段的证书均采用某个证书吊销列表,需要吊销证书时仅在该吊销列表中添加证书信息,同样,其它证书吊销列表不受影响。
在 Windows 操作系统中,优先使用证书吊销列表。
Windows 下的证书吊销列表
2.1.3. OID
OID(Object Identifier)即“对象标识符”。是用于无歧义表示一个对象的编码,其使用由区间 (0, 16000000) 内的数构成的节点连接而成(如:1.3.8.155641.2.1)。
每个节点分别表示其一个对象,节点后跟的节点为子节点。
2.2. 证书颁发机构
证书颁发机构(Certificate Authority)简称“CA”。证书颁发机构是用于向用户提供一个受信任的根,来保护用户的活动(网络通信、身份验证、合同签订、电子商务等)的角色。证书颁发机构必须保证自己的安全性、公正性、可信性。
一个证书颁发机构可以有多个受信任的根,以便于管理和向用户提供高安全性、高保密性的服务。公钥基础设施的所有认证均建立在证书链的基础上。
证书链(Certificates Chain)是由多个证书构成的证书序列结构。其由证书颁发机构证书开始,最终实体证书结束,用于确保最终实体证书是合法有效的。证书链开始的证书颁发机构(证书),我们称为根证书颁发机构(证书)。根证书颁发机构(证书)与最终实体(证书)中间的所有级别证书颁发机构(均为证书颁发机构证书)我们称为中间证书颁发机构(证书)。最终实体证书(用户证书)是整条证书链的结束,也是用户保留有私钥的唯一一级证书。同时,最终实体证书不能用于颁发证书。
通常情况下,证书颁发机构为了确保其下证书链的可信度、根证书颁发机构证书的安全,会使用由证书颁发机构根证书签发的二级证书颁发机构证书颁发最终实体证书(用户证书)。
部分证书颁发机构会向其他实体提供证书的签发权,比如向该组织签发二级(或其他级)的CA证书,甚至允许该实体继续签发子证书颁发机构证书。
因此我们经常可以看到的证书链通常是下列三种结构(未写明“第三方”的证书颁发机构均由根证书颁发机构所属实体负责):
根证书颁发机构
中间证书颁发机构
最终实体证书
根证书颁发机构
中间证书颁发机构(第三方)
最终实体证书
根证书颁发机构
中间证书颁发机构(第三方)
中间证书颁发机构(第三方)
最终实体证书
一个合格的证书颁发机构必须有撤销(吊销)、续订本证书颁发机构直接签发的各级证书的能力,同时必须具备符合规范,从而可以让用户、软件可以正常、正确的获取到证书信息的能力。
为了确保证书具备证书颁发机构所需要的要求,通常会在证书扩展中添加这些扩展: 授权密钥标识符、使用者密钥标识符、授权信息访问、CRL 分发点、增强型密钥用法、证书策略。
任何证书颁发机构必须严格管理、妥善保存直接隶属于本颁发机构的所有证书的私钥,对于用户而言,必须严格管理、拓展保存所有自己持有的证书的私钥。一旦证书颁发机构发现任何私钥泄露,证书颁发机构必须立刻吊销已泄露私钥的最终实体证书或证书颁发机构证书。否则证书颁发机构会失去安全性和可信性。
为了确保证书确实来自期望的证书颁发机构颁发,证书颁发机构需要使证书具有特定标识符,标识符必须是安全的,唯一的。常见的标识符有:授权密钥标识符、使用者密钥标识符、哈希值(证书“指纹”)。
2.2.1. 根证书颁发机构证书
根证书颁发机构证书(Root Certificate)简称“根证书”。根证书颁发机构证书是自签名的证书颁发机构证书,是所有二级证书的颁发证书。
一个证书颁发机构的根证书是最重要的,也是最宝贵的。因为现有安全认证体系通常在其内部有一个包含其认为可信的根证书、最终实体证书的集合,这个集合称为可信列表。 在验证过程中,会对比证书链中的根证书是否包含于其的可信列表,若不包含则不信任基于此根证书的证书链。
在 Windows 操作系统中,微软通过注册表来保存可信列表。因此在 Windows 操作系统中对可信列表进行操作(如增删根证书)的实质为注册表操作。同样,微软也在 Windows 操作系统也为此可信列表进行了功能扩展,来确保其可信列表内部根证书是由微软管理的。例如 Windows 操作系统可信列表内置的根证书包含: “密钥用法(属性)”、“扩展密钥用法(属性)”、“扩展的验证(属性)”等重要属性,也有一些不那么重要的属性如友好名称、证书描述。这些属性实现了标准规范中证书扩展的功能,但不是证书扩展。
通常被微软信任的证书颁发机构均内置于操作系统的可信列表中,由 Windows 操作系统自动安装的,因此在 Windows 操作系统中那些根证书颁发机构的根证书不使用证书扩展来控制,而是直接由可信列表的“属性”来控制。通过证书“属性”项指定的值可以被随时修改,而证书扩展指定的值则不可以。
除此之外,微软的可信列表中的部分根证书还有一个特殊的属性:扩展的验证(属性),它将实现扩展验证的证书功能。关于此属性的详细信息将在后面的小节中介绍。
2.2.2. 扩展验证的证书
扩展验证(Extended Verify)简称“EV”。扩展验证指证书颁发机构对证书使用者进行了额外的身份验证并标识在证书内,同时证书颁发机构需要对签发扩展验证的证书的各级证书颁发机构证书的安全性提供最高级别的安全保障。
证书颁发机构的根证书直接决定能否颁发扩展验证的证书,而扩展验证的证书则必须符合标准规范。
例如在证书的基本部分中“使用者”扩展项的值就必须额外新增一些项及其对应的值,且部分新增项的值必须与部分原有项的值对应。
如果一个证书颁发机构想要颁发扩展验证的 SSL 证书或 扩展验证的代码签名证书,二者均需要证书颁发机构的根证书在 Windows 可信列表中具有“扩展的验证”属性,并且前者还需包含于浏览器的可信列表(对于使用操作系统可信列表的浏览器(如:Internet Explorer)则不需要)。
如果扩展验证的证书不符合规范,那么他将不会发挥扩展验证的作用。
2.3. 证书注册审批机构
证书注册审批机构(Registration Authority)简称“RA”。证书注册审批机构对申请证书颁发机构颁发证书的实体进行身份验证、审核,通常由证书颁发机构所属实体负责。证书注册审批机构可以理解为证书颁发机构颁发证书时的代理,通常申请某一证书颁发机构颁发证书时,会先提交给证书注册审批机构。
2.4. 签名证书时间戳
签名证书时间戳(Signed Certificate Timestamp),简称“SCT”。签名证书时间戳技术的诞生致力于解决“证书透明度”,在此项技术提出前的时间,国际公认证书颁发机构 Diginotar、Comodo 遭到入侵,造成大量非法证书颁发。随后,Google 发现中国网络信息中心(CNNIC)未经一些域名持有主体授权,颁发了该域的非法证书。这些事件暴露出受信任的证书颁发机构颁发的证书可能被用于“中间人攻击”,因此 Google 提出了签名证书时间戳技术。
现在,所有的扩展验证的证书均需提供签名证书时间戳,同时所有的 SSL 证书也必须包含签名证书时间戳。
签名证书时间戳为符合 X.509 格式,ASN.1 表示方法,IETF 标准与 RFC 文件规定的数据。签名证书时间戳也分为不同的版本,截至目前共有一个版本(版本 1)。
其数据结构如下:
签名证书时间戳
版本
日志 ID
时间戳
扩展部分
签名
为了获取签名证书时间戳,证书颁发机构必须先颁发预签发证书,将其提交到证书透明度日志服务器,服务器将会对提交的证书进行记录。同时证书透明度日志服务器必须为可信的(证书透明度日志服务器需被提交至 Google,完成为期一年的测试)。
通过证书透明度技术,任何域的主体在任何时间均可发现本域的证书情况(如是否存在其他证书颁发机构私自颁发的情况),也对证书颁发机构起到了很好的监督、约束。
- 数字证书与扩展
现代基于数字证书的安全加密认证体系所使用的证书为 V3 版本证书,V3 证书最重要的一点即为其支持了扩展部分,从而可以通过在扩展部分添加指定扩展实现认证所需的特定功能。
下面会对此进行详细讲解,以便于自建公钥基础设施的证书颁发机构可以颁发符合标准规范的证书。
需要注意,标准规定的数字证书扩展项的值支持的标识符仅有:URI,Email,RID,DNS,IP,otherName。其中 URI 仅支持未加密的协议(如 HTTP 而不是 HTTPS),部分软件层会对此进行扩充从而额外支持部分协议(如 HTTPS)但请不要使用此类协议!
3.1. 密钥标识符
密钥标识符通常为证书公钥的哈希值,也可为证书的主题信息(用于根证书),由于主题信息可以随意填写,因此绝大多数位置均使用哈希值。
3.1.1. 授权密钥标识符
授权密钥标识符(Authority Key Identifier),简称“AKI”,短名称为“authoritykeyIdentifier”,OID为 2.5.29.35,在 RFC 5280 中被定义,为非关键扩展。此扩展通常在所有证书中出现,用以标识和验证证书的颁发证书的主体信息,通常为颁发证书主题信息的哈希值,但也有例外(根证书中可能为明文主题信息)。
在 OpenSSL 配置文件中添加下方代码来添加授权密钥标识符扩展:
authorityKeyIdentifier=keyid
图片(Windows 下授权密钥标识符扩展)
3.1.2. 主体密钥标识符
使用者密钥标识符(主体密钥标识符,Subject Key Identifier),简称“SKI”,短名称为“subjectkeyIdentifier”,OID为 2.5.29.14,在 RFC 5280 中被定义,为非关键扩展。此扩展通常在所有证书中出现,用以标识和验证证书的主体信息,为主题信息的哈希值。
在 OpenSSL 配置文件中添加下方代码来添加使用者密钥标识符扩展:
subjectKeyIdentifier=hash
图片(Windows 下使用者密钥标识符扩展)
3.2. 授权信息访问
授权信息访问(Authority Info Access)简称“AIA”,短名称为“authorityInfoAccess”,OID为 1.3.6.1.5.5.7.1.1,在 RFC 5280 中被定义,为非关键扩展。其用处为在证书中内嵌证书颁发机构证书和联机证书状态协议的位置信息。以便软件验证证书、证书链的合法、有效性。
在 OpenSSL 配置文件中添加下方代码来添加授权信息访问扩展:
authorityInfoAccess = OCSP;URI:http://ocsp.levimarvin.site:8080,caIssuers;URI:http://levimarvin.site/abc.crt
如果证书中缺少此扩展,软件将无法建立、验证证书链。在 Windows 操作系统中,会提示用户:“Windows 缺少某些信息,无法验证该证书的颁发者。”
图片(Windows 下授权信息访问扩展)
3.2.1. 联机证书状态协议
联机证书状态协议(Online Certificate Status Procotol)简称“OCSP”,短名称为“OCSP”,OID 为 1.3.6.1.5.5.7.48.1,在 RFC 5280 中被定义。联机证书状态协议为软件提供了快速、安全的证书验证协议。通过向证书中指定的OCSP 响应器发送请求,软件即可获取到该证书的状态。
联机证书状态协议大大缓解了使用证书吊销列表的压力,因此越来越多的软件优先选择使用联机证书状态协议。
OCSP 响应器(OCSP Responder)是运行 OCSP 并返回 OCSP 消息的服务端,用于处理从客户端发来的 OCSP,并查询 OCSP 消息中的证书在证书颁发机构的状态,同时可以告知客户端证书的颁发者信息,从而可以不用添加证书颁发机构颁发者(但仍然建议添加作为 OCSP 服务端不可用时的备用方案)。OCSP 协议由 Google 推行,因此在基于 Chrome 内核的浏览器中,优先使用 OCSP 来检查证书的状态。
一个证书的授权信息访问扩展可以有多个“联机证书状态协议”,用于指定在不同的网络位置上获取信息。与证书吊销列表不同,联机证书状态协议响应器可以是共用的,只需要在响应器内部对收到的请求进行分类处理。
需要注意:
联机证书状态协议需要专用的签名证书来对发送的内容和传输过程进行加密;
联机证书状态协议服务端返回的结果几乎为实时响应,除非设置与下一次请求的间隔,否则下次客户端请求的时间为实时;
联机证书状态协议服务端收到请求后会自动完成操作,无需手动发布响应结果等类的文件。
3.2.2. 证书颁发机构颁发者
证书颁发机构颁发者(Certificate Authority Issuers)简称“CAI”,短名称为“caIssuers”,OID 为 1.3.6.1.5.5.7.48.2,在 RFC 5280 中被定义。证书颁发机构颁发者为软件提供了该证书颁发者的位置,用于软件建立证书链,验证证书颁发者。
一个证书的授权信息访问扩展可以有多个“证书颁发机构颁发者”,用于指定在不同的网络位置上获取信息。
3.3. CRL 分发点
CRL 分发点(CRL Distribution Points)简称“CDP”,短名称为“crlDistributionPoints”,OID 为 2.5.29.31,在 RFC 5280 中被定义,为非关键扩展,可设置为关键扩展。其用处为在证书中内嵌证书吊销列表的位置信息。以便软件验证证书、证书链的有效性。
在此扩展中可以指定多个证书吊销列表文件的位置。
在 OpenSSL 配置文件中添加下方代码来添加 CRL 分发点扩展:
crlDistributionPoints = URI:http://levimarvin.site/abc.crl
添加 CRL 分发点扩展中多个 CRL 分发位置:
crlDistributionPoints.0 = URI:http://levimarvin.site/abc1.crl
crlDistributionPoints.1 = URI:http://levimarvin.site/abc2.crl
图片(Windows 下 CRL 分发点扩展)
3.4. 增强型密钥用法
增强型密钥用法(Extended Key Usage)简称“EKU”,短名称为“extendedKeyUsage”,OID 为 2.5.29.37,在 RFC 5280 中被定义,为非关键扩展,可设置为关键扩展。
增强型密钥用法扩展对证书的预期目的进行了细分,证书添加此扩展后,将不能用于未在此扩展中指定的目的。
在 OpenSSL 配置文件中添加下方代码来添加增强型密钥用法扩展:
extendedKeyUsage=serverAuth, clientAuth, timeStamping, msSGC, nsSGC, ipsecEndSystem, ipsecTunnel, ipsecUser, iKEIntermediate, msSmartcardLogin, id-kp-eapOverPPP, id-kp-eapOverLAN, pkInitKDC, pkInitClientAuth
3.5. 主体可选名称
主体可选名称(使用者可选名称,Subject Alternative Name),短名称为“subjectAltName”,OID 为 2.5.29.17,在 RFC 5280 中被定义,为非关键扩展。其通常用于 SSL 证书,标识某一证书可以用在的域、IP、邮箱等。
在 OpenSSL 配置文件中添加下方代码来添加主体可选名称扩展:
subjectAltName = DNS:levimarvin.site
添加主体可选名称扩展中多个主体可选名称:
subjectAltName = DNS:levimarvin.site, DNS:levimarvin.site, IP:127.0.0.1
图片(Windows 下的主体可选名称扩展)
3.6. SCT 列表
SCT 列表(SCT List)简称“SL”,短名称为“ct_precert_scts”,OID 为 1.3.6.1.4.1.11129.2.4.2,在 RFC 6962 中被定义,为非关键扩展。其作用为在证书中内嵌证书的透明度信息。
证书透明度日志服务器需要单独编译与运行现有的开源证书透明度日志服务器,或自己编写一个。
在 OpenSSL 配置文件中添加下方代码来添加 SCT 列表(添加的 DER 编码二进制数据来自于证书透明度日志服务器返回的数据):
ct_precert_scts=DER:04:82:01:6c:01:6a:00:77:00:…
图片(Windows 下的 SCT 列表扩展)
3.7. “基本约束”与“密钥用法”
基本约束(Basic Constraints),短名称为“basicConstraints”,OID 为 2.5.29.19,在 RFC 5280 中被定义,为关键扩展。其作用为对证书作出基本限制:
证书类型(证书颁发机构证书/最终实体证书)
证书颁发机构长度(可选)
通过证书中的基本约束,证书颁发机构可以限制子证书颁发机构仅颁发最终实体证书。
在 OpenSSL 配置文件中添加下方代码来添加基本约束(关键):
basicConstraints=critical,CA:FALSE
密钥用法(Key Usage),短名称为“keyUsage”,OID 为 2.5.29.15,在 RFC 5280 中被定义,为关键扩展。
图片(Windows 下的密钥用法)
密钥用法可以对证书的用途作出基本限制,但如需更加细分的限制,则需要额外添加增强型密钥用法扩展。
在 OpenSSL 配置文件中添加下方代码来添加密钥用法:
keyUsage=critical,digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, encipherOnly, decipherOnly
图片(Windows 下的基本约束)
3.8. 证书策略
证书策略(Certificate Policies),短名称为“certificatePolicies”,OID 为 2.5.29.32,在 RFC 5280 中被定义,为非关键扩展。
通过证书的证书策略扩展,证书颁发机构可以让用户知情证书颁发机构采取何种策略、方式、保障来保护其证书颁发机构的安全性和颁发的证书。
证书策略扩展项的值可以由多个,在值中,一个策略 ID 可以对应多个证书策略地址,可以有多个策略 ID。策略 ID 可以为任意的 OID。
在 OpenSSL 配置文件中添加下方代码来添加证书策略扩展:
certificatePolicies=ia5org,@certpol0_sect
[certpol0_sect]
policyIdentifier=1.2.3.4.5
CPS.0=http://levimarvin.site/CPS
图片(Windows 下的证书策略扩展)
- 搭建与技术细节
4.1. 证书颁发机构
4.1.1. 基本要求
证书颁发机构需要一个注册过的 OID 用于其身份、策略、目的标识。
一般注册到的 OID 由两种:
2.23.0 根 OID 分配的子 OID
1.3.6.1.4.1.0 根 OID 分配的子 OID
前者为国家分配,后者为国际互联网代理成员管理局(IANA)分配。
在中国,由国家 OID 注册中心分配。
由某一国家分配的 OID 在分配前,相应的管理局会对注册申请实体进行审查,但也正因如此,使用国家 OID 的证书颁发机构易受到实体注册国、OID 注册国的干涉,但由于会对其进行审查,可信度更高。
由国际互联网代理成员管理局(IANA)分配的 OID 在分配前,不会对申请实体进行审查,可信度与前者相比不高,但不易受到 OID 注册国的干涉。
证书颁发机构需要可以提供服务且可以在国际上被访问的服务器来部署相关服务。如:HTTP/HTTPS 服务器、OCSP 服务器、CT 日志服务器(如果你被国际公认可以没有)。
使用 Nginx 等 Web 服务端可以部署 HTTP/HTTPS 服务。
使用 OpenSSL 可以生成、签发证书,证书吊销列表和部署简单的OCSP 服务。
创建证书吊销列表
openssl ca -gencrl -crldays 有效期(日) -cert CA证书.crt -keyfile CA证书私钥.key -md 算法(SHA、MD等) -out 输出文件.crl -config 配置文件.cnf
Tips:
"-crldays"可以被"-crlhour"替代,替代后的有效期单位则为小时。不推荐将有效期设置的太短,一周足够。否则CA需要频繁的生成、发布最新的CRL文件。
算法可以为"SHA1"、"SHA256"、"SHA384"、"SHA512"、"MD1"、"MD2"、# "MD5"等等,有效即可。同时选择算法时也应考虑操作系统兼容性。
运行 OCSP 服务器
ocsp -index demoCA/index.txt -port 8080 -nmin 1 -rsigner oc.crt -rkey oc.key -CA CA的证书文件.crt -out 日志文件.log
需要注意:使用 OpenSSL 部署的服务依赖于 OpenSSL 的文本数据库。
使用 Google 的 Certificate Transparency Go 可以部署证书透明度日志服务。
最好的方案是自己开发一个自动化的公钥基础设施系统。
4.1.2. 数字证书
所有的数字证书(根证书除外)必须包含前一大章节中所述的扩展,证书若使用哈希算法,则必须使用 SHA256 及以后的算法。如:sha256RSA。
现在越来越多的证书颁发机构使用椭圆曲线算法(如:ECDSA、ECDH),比传统的非对称加密算法所需成本更低,更加安全。
目前世界上不存在绝对安全的加密算法与安全体系,随着科技进带来的算力提升与时间推移,现有的加密算法与安全体系终将淘汰。
对于扩展验证的证书,其证书及证书链的根证书必须在软件中内置其注册过且分配用于扩展验证证书的 OID。
对于加密 OCSP 响应的证书必须为专用的证书。该证书可以由证书颁发机构根证书签发,以便于对该根证书签发的所有证书颁发机构的所有 OCSP 响应签名。
由于 OCSP 响应证书不能包含授权信息访问扩展,CRL 分发点扩展,所以证书颁发机构无法控制 OCSP 证书,因此该证书的有效期必须控制在半年以内。
OCSP专用证书必须有OCSP不撤销检查扩展,密钥用法仅可以包含:
Digital Signature, Non-Repudiation, Key Encipherment
增强型密钥用法扩展必须仅包含“OCSP 签名”用法,此外证书也必须为最终实体证书。
某些情况下,为了使 Windows 操作系统兼容,可以再颁发一个 OCSP 证书,证书中包含应用程序策略扩展,策略标识符为“OCSP 签名”。
4.2. 证书注册审批机构
数字证书审批机构需要提供用户一个提交证书颁发申请的接口,并对来源于此接口的信息进行审核、处理,若符合公钥基础设施的要求,则向证书颁发机构提交,不符合则向用户告知。
证书注册审批机构需要可以提供服务且可以在国际上被访问的服务器来部署相关服务。某些情况下,证书注册审批机构与证书颁发机构在同一服务器上。
- 维护与审计
根据国际上的标准和规范,证书颁发机构必须每隔一定周期向有注册资格的审计公司提交审计,用于确定证书颁发机构是否可以公平、公正的保障用户的信息安全。
由于证书颁发机构根证书十分的宝贵,因此绝大多数的证书颁发机构均将其下根证书颁发机构私钥离线保存,用于保障安全。签发证书时,使用由根证书签发的下级证书颁发机构证书签发。