数字证书(Digital Certificate),一般指公钥证书(Public Key Certificate,PKC),类似于我们生活中的身份证,用于标识网络中的用户(计算机)身份,里面记有姓名、组织,邮箱,地区,国家等个人信息,以及属于此人的公钥,还包含由认证机构(Certification Authority,CA) 施加的数字签名。公钥证书也简称为证书(Certificate)。
上面的描述是不是很抽象,下面我们来具体看一看一个证书包含的具体数据。下面的内容是通过Java程序从证书文件HF_Bank_IT.cer中读取到的,它是一个自签名的CA证书。后面的章节会告诉大家如何生成它,现在我们来直观的看看一个证书都包含那些内容:
[
[
Version: V3
Subject: [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
modulus: 30392530841957851304244489180669251252057838529091246523524299180083692395190504890307461892583376536576898890489957493195076098504767534780043809690238041580816476752455592905809528495378941431927500238724034716722871702839602713815079396803229560896649605178024173853337676989753258808655685287489545770005697878745045069299976044649338425795586848360590347118480450655356777461954161338224454113339009560097465924499347901862999990078430102416526514144562357669861243080932277971477213962232852273343331679010948656229430872285850576015136738277250540937256578921492867921321354384862454427130281343301046370883553
public exponent: 65537
Validity: [From: Sat Jan 14 11:28:00 CST 2023,
To: Fri Jan 14 11:28:00 CST 2033]
Issuer: [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN
SerialNumber: [ 6b873456 87a86b10]
Certificate Extensions: 5
[1]: ObjectId: 2.16.840.1.113730.1.13 Criticality=false
Extension unknown: DER encoded OCTET string =
0000: 04 11 16 0F 78 63 61 20 63 65 72 74 69 66 69 63 ....xca certific
0010: 61 74 65 ate
[2]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
[3]: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
Key_CertSign
Crl_Sign
]
[4]: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
NetscapeCertType [
SSL CA
S/MIME CA
Object Signing CA]
[5]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 4C BD 22 CE 6E F2 3F D7 22 FE F1 D8 41 83 F5 DA L.".n.?."...A...
0010: 16 1C 2B 4E ..+N
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 57 8B 93 16 A1 D3 2F 1E C2 B1 12 81 7E 4F 56 7F W...../......OV.
0010: 62 EC 3C 60 4A A0 88 3C A4 43 CA 61 7D 30 34 BF b.<`J..<.C.a.04.
0020: 92 49 7C 65 E7 EC B3 0F 7A CF 76 57 73 B7 50 C2 .I.e....z.vWs.P.
0030: 8D A5 67 86 A4 46 C3 F0 C6 8C 0E B8 7C E9 38 7F ..g..F........8.
0040: 2F 34 53 39 E7 2C 34 A3 B9 A0 F6 39 4E E6 DF 77 /4S9.,4....9N..w
0050: 6E B5 E4 0E 4D 2D 0D 51 78 1C 3D 6F D2 A7 DB C8 n...M-.Qx.=o....
0060: CB 6F CF DB 42 06 A9 B4 AD EE 3E A2 00 29 9D B1 .o..B.....>..)..
0070: 53 30 78 87 D9 63 24 0E 31 4A B4 C5 BA 64 23 5D S0x..c$.1J...d#]
0080: A8 0F A1 79 9A 23 2D 8E E6 9B E6 42 E3 F9 EF 5A ...y.#-....B...Z
0090: FF D8 56 A5 0A CA B4 80 2F D6 A2 3D A4 C4 F6 59 ..V...../..=...Y
00A0: 08 0B 9C 21 6E 31 AF 42 7B 3A E8 BE 96 21 7A 86 ...!n1.B.:...!z.
00B0: 98 AF 62 DA 9E 7A B8 93 CE DB 49 E2 AA D4 BA 8F ..b..z....I.....
00C0: 5B AD 08 3C C3 8A 22 E8 5D 22 7B 4A B2 7E FF 2F [..<..".]".J.../
00D0: 9A B0 4A FC 48 28 E7 C2 2F 41 82 69 E1 05 4C A5 ..J.H(../A.i..L.
00E0: 04 DB 13 5D 6F FD 09 0B B0 76 80 11 D3 63 96 46 ...]o....v...c.F
00F0: 0A 18 5C 94 DB 27 FF 1B 46 12 0E 73 A9 C6 3A 9C ..\..'..F..s..:.
]
我们可以看到一个证书主要包含下面这些内容:
字段 | 内容 | 描述 |
---|---|---|
Version | V3 | 数字证书标准 X.509的第3个版本,也是目前最新的一个版本 |
Subject | [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN | 证书所有者 |
CN | www.hf.com | Common Name,通用名称。对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于客户端证书则为证书申请者的姓名。 Chrome 58以后不再使用CN校验地址(就是就是浏览器地址栏URL中的那个地址host)了,而是使用SAN,注意配置里写对,IE 11还是使用CN。 |
O | HF Bank | 单位名称 (Organization Name) 简称:O 字段,对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于客户端单位证书则为证书申请者所在单位名称 |
OU | HF Bank IT | Organization Unit,组织单位,例如子域名或分公司。 |
L | Xian | Locality,所在地区 |
ST | Shannxi | State/Provice,所在省份 |
C | CN | Country,所在国家 |
Signature Algorithm | SHA256withRSA | 数字签名算法 |
Key | Sun RSA public key, 2048 bits | 公钥信息 |
modulus | 3039253084195785130424448918066925125205783852909124652352429918008369239519050489030746189258337653657689889048 99574931950760985047675347800438096902380415808164767524555929058095284953789414319275002387240347167228717028396027 13815079396803229560896649605178024173853337676989753258808655685287489545770005697878745045069299976044649338425795 58684836059034711848045065535677746195416133822445411333900956009746592449934790186299999007843010241652651414456235 76698612430809322779714772139622328522733433316790109486562294308722858505760151367382772505409372565789214928679213 21354384862454427130281343301046370883553 |
模数,RSA公钥的两个信息之一,和指数一起可以生成公钥 |
public exponent | 65537 | 指数 |
Validity | From: Mon Jan 02 18:46:15 CST 2023, To: Wed Dec 09 18:46:15 CST 2122 |
有效期,创建时间,过期时间 |
Issuer | [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN | 签发者 |
SerialNumber | 0d18365b | 证书序列号,认证机构颁发证书时给与的编号 |
Certificate Extensions | 证书扩展 | |
Certificate Fingerprint | MD5: 10:4D:B9:CE:F2:9B:18:DE:75:3F:2E:8F:E8:84:83:EE SHA1: 84:87:C2:5D:DE:54:34:4A:0F:3A:28:1A:73:7D:13:9D:C3:4B:B2:1A SHA256: 62:22:1C:E8:5A:46:83:44:C2:E6:A3:EE:5D:21:6B:66:95:F9:A2:66:9C:01:AB:49:76:23:F6:D5:C8:A1:AB:8F |
证书指纹,分别由3中摘要算法生成 |
Algorithm | SHA256withRSA | 数字签名算法 |
Signature | 数字签名 |
X.509 是密码学里公钥证书的格式标准。
X.509 证书己应用在包括TLS/SSL(WWW万维网安全浏览的基石)在内的众多 Internet协议里.同时它也用在很多非在线应用场景里,比如电子签名服务。X.509证书里含有公钥、身份信息(比如网络主机名,组织的名称或个体名称等)和签名信息(可以是证书签发机构CA的签名,也可以是自签名)。对于一份经由可信的证书签发机构签名或者可以通过其它方式验证的证书,证书的拥有者就可以用证书及相应的私钥来创建安全的通信,对文档进行数字签名。
另外除了证书本身功能,X.509还附带了证书吊销列表和用于从最终对证书进行签名的证书签发机构直到最终可信点为止的证书合法性验证算法。
X.509是ITU-T标准化部门基于他们之前的ASN.1定义的一套证书标准。
在X.509里,组织机构通过发起证书签名请求(CSR)来得到一份签名的证书。首先需要生成一对钥匙对,然后用其中的私钥对CSR进行签名,并安全地保存私钥。CSR进而包含有请求发起者的身份信息、用来对此请求进行验真的的公钥以及所请求证书专有名称。CSR里还可能带有CA要求的其它有关身份证明的信息。
然后CA对这个专有名称发布一份证书,并绑定一个公钥。
组织机构可以把受信的根证书分发给所有的成员,这样就可以使用公司的PKI系统了。
像Firefox, IE, Opera, Safari 以及Google Chrome都预装有早就确定的根证书列表,所以使用主流CA发布的证书SSL都直接可以正常使用。浏览器的开发者直接影响着它的用户对第三方的信任。FireFox就提供了一份csv/html格式的列表X.509也定义了CRL实现标准。另一种检查合法性的方式是OCSP。FireFox 3开始就默认打开了这项检查功能,Windows从Vista版本以后也一样。
证书组成结构标准用ASN.1(一种标准的语言)来进行描述。
X.509 v3数字证书结构如下:
仅有证书规范还不足以支持公钥的实际运行,我们还需要很多其他的规范,例如证书应该由谁来颁发,如何颁发,私钥泄漏时应该如何作废证书,计算机之间的数据交换应采用怎样的格式等。
**公钥基础设施(Public-Key Infrastructure, PKI)**是为了能够更有效的运用公钥而制定的一系列规范和规格的总称。PKI只是一个总称,而并非指某一个单独的规范或规格。
PKI是一个包括硬件、软件、人员、策略和规程的集合,用来实现基于公钥密码体制的密钥和证书的产生、管理、存储、分发和撤销等功能。
PKI体系是计算机软硬件、权威机构及应用系统的结合。它为实施电子商务、电子政务、办公自动化等提供了基本的安全服务,从而使那些彼此不认识或距离很远的用户能通过信任链安全地交流。
一个典型的PKI系统包括PKI安全策略、软硬件系统、证书机构CA、注册机构RA、证书发布系统和PKI应用等。
实际网络环境中不可能只有一个CA.多个认证机构之间的信任关系必须保证原有的PKI户不必依赖和信任专一的CA,否则将无法进行扩展、管理和包含。 信任模型建立的目的是确保一个认证机构签发的证书能够被另一个认证机构的用户所信任。常见的信任模型包括以下四种:
一个通用的场景:Alice想要给Bob发消息,但是首先要确认Bob是身份是可信的。所以Alice首先拿到Bob的证书(从哪里取到证书,见第二张图),并通过认证机构Trent验证Bob证书的合法性。如果认证成功,就用Bob的公钥加密数据,发送给Bob。
Bob首先在认证机构注册公钥,认证机构将生成的证书放在仓库(例如基于LDAP V3规范的服务器)中,供用户下载,比如Alice。
上以节提到认证机构的分层信任模型,根CA,中间CA和终端用户。
对应到证书上,证书也是分层级的,CA根证书,中间证书,用户证书,并且不同层级的证书形成了一个信任链。
**证书链(也就是RFC 5280里的证书路径
)是从终端用户证书后跟着一系列的CA证书,而通常最后一个是自签名证书(CA根证书),并且有如下关系:
证书链用于检查目标证书(证书链里的第一个证书,用户证书)里的公钥及其它数据是否属于其持有者。检查是这么做的,用证书链中的下一个证书的公钥来验证它的签名,一直检查到证书链的尾端,如果所有验证都成功通过,那个这个证书就是可信的。
例如我们可以看到,百度的证书所在证书链长度为3,是由中间证书签发的。
如图所示就是一个由根证书,中间证书,用户证书等组成一条完整证书信任链。只有当整个证书信任链上的各个证书都有效时,浏览器才会认定当前颁发给用户的证书是有效和受信任的。而证书链文件是指除了用户证书以外中间证书和根证书组成的证书文件称之为证书链文件。证书链文件是证书部署和验证证书是否可信环节中最重要的组成部分。
根证书
是受信任CA证书颁发机构给自己颁发的证书,是信任链的起始点。浏览器判断根证书是否受信任主要是通过检索浏览器的根证书库可信任列表里是否存在。如果存在浏览器就会信任该根证书。目前有的浏览器会自建根证书库,例如火狐浏览器,有的浏览器会使用其他浏览器的根证书库或者调用操作系统的根证书库,例如谷歌浏览器。根证书信息查看可以通过点击根证书后查看证书信息后显示根证书的颁发者以及有效期等信息。
中间证书
是根证书颁发机构CA对中间证书颁发机构的公钥进行数字签名得到的证书。中间证书的作用主要是为了保护根证书。因为如果直接采用根证书签发证书,一旦发生根证书泄露,将造成极大的安全问题。中间证书可以不止一个,目前我们经常看到有两级中间证书的,原则上中间证书层数越多,根证书越安全。但是一般情况下最多也不超过2级。
用户证书
是由中间证书CA签发给用户的证书。用户证书由中间证书证明可信。用户证书是浏览器上实际体现和使用的证书。用户证书可以通过点击小锁后查看到该证书颁发给哪个域名或者ip,证书有效期,颁发机构等信息。
根证书签发中间证书,中间证书签发用户证书,用户证书就无法再签发证书了。
认证时先从受信列表中查询根证书,然后用根证书认证证中间证书,最后用中间证书的公钥认证用户证书。
所以说,客户端和服务端在进行网络通信时,不止会发送证书,证书链也会一起发送,这样才能做到逐级认证。
通常有以下几种方式来生成证书:
以下是国际权威数字证书颁发认证机构的“三巨头”:
除此之外还有:
DigiCert: https://www.digicert.com/
通常,这种由国际权威数字证书颁发认证机构颁发的数字证书需要向用户收取昂贵的申请和维护费用。但并不是所有的国际权威数字证书颁发认证机构都收费,CAcert:http://www.cacert.org 就是一个免费的数字证书颁发国际组织。随着用户群的增大和颁发手段的可信性,这种免费的数字证书可信度也越来越高。
申请数字证书之前,您必须先生成证书的密钥文件和CSR文件。CSR文件是您的公钥证书原始文件,包含了您的服务器信息和您的单位信息,需要提交给CA认证中心进行审核。
CSR的全称是证书签发请求,即证书请求文件,也就是证书申请者在申请数字证书时由CSP(加密服务提供者)在生成私钥的同时也生成证书请求文件,证书申请者只要把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件,也就是颁发给用户的证书。
XCA(X Certificate and key management) 是作为证书和密钥存储,以及作为签发证书的签名应用程序,是一个开源的工具,底层还是基于openssl的类库和API的。
首先需要下载并安装工具,官网地址为:https://www.hohnstaedt.de/xca/index.php/download
安装完成后,首先创建数据库,然后切换到CSR页签,点击“新建请求”按钮:
假设我们要为HF银行的IT部门的网站申请SSL证书,填写申请者信息,并同时生成私钥:
公司:HF银行
部门:HF银行IT部门
网站域名:www.hf.com
然后导出CSR文件:
导出的PEM文件是文本格式,用文本编辑器打开,内容如下:
-----BEGIN CERTIFICATE REQUEST-----
MIICzTCCAbUCAQAwgYcxCzAJBgNVBAYTAkNOMRAwDgYDVQQIEwdTaGFubnhpMQ0w
CwYDVQQHEwRYaWFuMRAwDgYDVQQKEwdIRiBCYW5rMRMwEQYDVQQLEwpIRiBCYW5r
IElUMRMwEQYDVQQDEwp3d3cuaGYuY29tMRswGQYJKoZIhvcNAQkBFgxhZG1pbkBo
Zi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKyR+IiiB2oqdC
a3m4+3s6003qlSuVNSxbben+15TpZjwwXbWXt9CieNUR6TUMtqUvNhtAZHCoMF3Q
j06O6n2IaEAufLPcTpICsgoHks+/009t2qZGd2yNMwg7QAXcxkYZFT/8gp0L2qM0
o9J+fPyKkn86Tt1bJ8kDZgujCAV9h9Uqh8Ka+iiH7Xc2DqCMnu9lDx1dId0D3b/k
gjHRjHjH5YzxSeGiVhgQDWOt+ZQM6g1+GVLCNAM5PJbACKf1btH70U69+MojB7In
l1VnyKrN+frRJRG/GylNoemIMH7wNU5Z2l+d5sJdVgyV4A8uwOSzbFzqQeOLSRcG
MoHtSLc/AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAcxOBXo1awOADrlG5R72o
u+RK+tBqev8zvDu7SN0okkJB4S2mEInL8LWykb0vjv5bnNf6ra5k9J/LaHa4cnW3
6C8Npgd3KyBAuXliBff7j5l6dVupa9YhPgPh7QiKGD+GEI0tOE8/LqKcOfC3HP5e
0Wzgr2gpnYLFWyVw80XuECJDwBwfXU5P8qySfCT4gzEWlPyeo+pW174AKfmuNGvC
OtFFItdnTwpRLqs2UjHTdSiJhUKH77g4VMgn3FVLprB68gCgdaZvt+/B3ZtUKHx1
CRqVM0qqopn6Rq2hLrDHh6UnbPU0OzrOkhyrb+Qq464W+2HP/dcTiojJTLMAAa8p
2A==
-----END CERTIFICATE REQUEST-----
私钥文件内容如下:
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAyskfiIogdqKnQmt5uPt7OtNN6pUrlTUsW23p/teU6WY8MF21
l7fQonjVEek1DLalLzYbQGRwqDBd0I9Ojup9iGhALnyz3E6SArIKB5LPv9NPbdqm
RndsjTMIO0AF3MZGGRU//IKdC9qjNKPSfnz8ipJ/Ok7dWyfJA2YLowgFfYfVKofC
mvooh+13Ng6gjJ7vZQ8dXSHdA92/5IIx0Yx4x+WM8UnholYYEA1jrfmUDOoNfhlS
wjQDOTyWwAin9W7R+9FOvfjKIweyJ5dVZ8iqzfn60SURvxspTaHpiDB+8DVOWdpf
nebCXVYMleAPLsDks2xc6kHji0kXBjKB7Ui3PwIDAQABAoIBACTXw73n8pv7U04y
/quILUxzxa1AKunx/jwiTSg6/Ngm9fqHnA2TnPlX4MZfS38i1AIu32akmP9FwlW5
I7m9is80uax4hakaMVcCB+Z2Wv5sIvs/hYQ6AGPrCKzTJf2FnIjEHpr/FA9qSsqu
lPjcNnnqwejTGU6NfOz8JlMZiv3SU65VnACywi5r9njfQcM/pBD7NEmJU0McCn7D
X+LlqwXjqyh9gA4yAxgsV3WCragcfGcgJJzlOce1IDxI2jPuS1YxzqZBpGSVD3XI
WKFoNdKvfNEo8J9XRLBqSJzi1oLHVUt+HgrImN1/XcBAru+WMnI0SEkZXOmvY67O
FgM+EMkCgYEA/sBaslwuEczngl1SKcLhjSsQ8oKLAbwLQYk8ZzDqd2poYvD90CXK
uejhwyZGKLf5dVf4j9Jgmo0VqZpystnwr479630f023qllEG1R/ZvG/sNpd1wDMj
P1QhFl+oJAAnGiknp+jMzwOAS6nJluHuo1bOge8VlwlYcmJs+/Czdt0CgYEAy8eQ
y2VUjTaEE9TkvcUhTwkClzKeUkYCfW+ty1pF5rb6dv01X8Y+q9QQTvviOJiu4SDO
RZHaXD82uuSA5gTitJ1DFVYKSsn6/MYqBf6Zs0mqRoBLwcU/JIabp/uWiWLIWVML
0sysTvBO5oipohGWCIHcQl3CBjkieNyUVdzY7ssCgYEAsNloHRnRAZp1vRJ7z3Hy
ksWq5i+pwHKCfeR/gkN7AZtlDAqwqKcTrSv2TjtrySiujL+dVnp9hc0blLoblf2m
ELn7nFcomOZdTCzDyYBq713jZaKPo/XcKkKFFbsiRpu0iXy4guAiDjQoBF7CC3Sc
7dd9VMZc/pUGSaH6dowKiiECgYEAi4I1s7nMl9yhsX4Hl4/UzOoLNv31e7foTn3d
iqFjx56vfDS/jLEJCNPm0lwJNNv6pa+y59gBmTPBwVNcl5zyo9oiKgI8i5UZ2mHE
NVRnX2HoS9nbg24JW3U4LVnFZosVRGnhZ1CuCmDkc1lOYOEPSQW2iEzt3xrQadQB
TYMjlN8CgYEAn7Qlns0qjUwrU6Dir5fu/gQ8ObjsFjNj2tt6Pnvmm7v6AagIsiTR
3T4s8UwUfKHYLvYZyDrjfw9uIajPSRV9okCFkRcuCqiOBOaBe2XP5nS1NLKMfqeN
oTUFC7zkJg6n7z89DJkL1E8K+zoMH0ppOR8Z6hpYbjhdpNK2b6jiwrM=
-----END RSA PRIVATE KEY-----
将导出的CSR文件提交至CA机构注册,从而获取到证书。
下图是在CAcert:http://www.cacert.org 上申请免费证书,提交CSR的页面。
申请证书的整个过程大致分为4个步骤:
拿到证书后,就可以与私钥一起来部署服务器了(后面的章节继续讨论)。
生成CSR步骤:
生成私钥(.key)–>生成证书请求(.csr)
# Generate CA private key
openssl genrsa -out HF_Bank_IT..key 2048
# Generate CSR
openssl req -new -key HF_Bank_IT..key -out HF_Bank_IT..csr
# 生成密钥库
keytool -genkeypair -alias hf-bank-it -keyalg RSA -validity 36500 -keystore HF_Bank_IT.jks
# 验证生成的密钥库文件
keytool -list -v -keystore icekeystore.jks
keytool -certreq -alias hf-bank-it -keystore HF_Bank_IT.jks -storepass 123456 -file HF_Bank_IT.csr
自签名证书是由不受信的CA机构颁发的数字证书,也就是自己签发的证书。与受信任的CA签发的传统数字证书不同,自签名证书是由一些公司或软件开发商创建、颁发和签名的。虽然自签名证书使用的是与X.509证书相同的加密密钥对架构,但是却缺少受信任第三方的验证。在颁发过程中缺乏独立验证会产生额外的风险,这就是为什么对于面向公众的网站和应用程序来说,自签名证书是不安全的。
自签名证书可以有许多不同的证书类型,包括SSL/TLS证书、S/MIME证书、代码签名证书等,其中最常见的证书类型是自签名SSL证书。与CA颁发的SSL证书不同,自签名证书通常指的是那些未经第三方验证,直接上传到私有公钥基础结构 (PKI) 的证书文件。
在XCA里选择“证书”标签页,点击“新建证书”按钮:
创建自签名证书,并应用CA模板:
切换到“持有者”页签,填写身份信息,并创建私钥:
点击OK按钮生成自签名证书。
CA根证书的生成步骤:
生成CA私钥(.key)–>生成CA证书请求(.csr)–>自签名得到根证书(.crt)(CA给自已颁发的证书)。
# Generate CA private key
openssl genrsa -out HF_Bank_IT.key 2048
# Generate CSR
openssl req -new -key HF_Bank_IT.key -out HF_Bank_IT.csr
# Generate Self Signed certificate(CA 根证书)
openssl x509 -req -days 36500 -in HF_Bank_IT.csr -signkey HF_Bank_IT.key -out HF_Bank_IT.crt
keytool -export -alias hf-bank-it -keystore HF_Bank_IT.jks -rfc -file HF_Bank_IT.cer
我们已经创建了自己的根证书,就可以作为CA,签发自己的子证书了。
假设HF银行的商业银行部门的网站需要进行HTTPS的升级,需要IT部门用根证书签发一个子证书,首先商业银行分部需要创建一个CSR,并且生成私钥:
然后我们选择新建一个证书,类型选择从CSR签发:
证书生成成功后,我们现在拥有了一个2级的证书链,包含俩个证书:
银行业务安全第一,所以如果需要部署双向HTTPS认证,还需要生成一个客户端证书。
假如客户是香港电讯,首先,客户会生成一个CSR和私钥,CSR发给HF银行来签发证书,自己保存私钥。
打开XCA,我们用CA根证书签发一个客户端证书:
最终,我们拥有了3张证书:
到这里,所有证书签发完毕,下一步,需导出证书和密钥库。
部署HTTPS时,我们可以选择两种认证方案:
用户证书的生成步骤:
生成私钥(.key)–>生成证书请求(.csr)–>用CA根证书签名得到证书(.crt)
服务端证书:
# private key
$openssl genrsa -des3 -out HF_Commercial_Bank.key 1024
# generate csr
$openssl req -new -key HF_Commercial_Bank.key -out HF_Commercial_Bank.csr
# generate certificate
$openssl ca -in HF_Commercial_Bank.csr -out HF_Commercial_Bank.crt -cert HF_Bank_IT.crt -keyfile HF_Bank_IT.key
客户端证书:
$openssl genrsa -des3 -out HF_Commercial_Bank_client.key 1024
$openssl req -new -key HF_Commercial_Bank_client.key -out HF_Commercial_Bank_client.csr
$openssl ca -in HF_Commercial_Bank_client.csr -out HF_Commercial_Bank_client.crt -cert HF_Bank_IT.crt -keyfile HF_Bank_IT.key
服务端证书:
keytool -gencert -alias hf-bank-it -keystore HF_Bank_IT.jks -storepass 123456 -infile HF_Commercial_Bank.csr -outfile HF_Commercial_Bank.cer
客户端证书:
keytool -gencert -alias hf-bank-it -keystore HF_Bank_IT.jks -storepass 123456 -infile HF_Commercial_Bank_client.csr -outfile HF_Commercial_Bank_client.cer
在XCA中选中根证书,点击“导出”按钮,选择导出DER格式的证书,用户服务端和客户端安装,形成证书链。
openssl x509 -req -days 36500 -in HF_Bank_IT.csr -signkey HF_Bank_IT.key -out HF_Bank_IT.crt
keytool -export -alias hf-bank-it -keystore HF_Bank_IT.jks -rfc -file HF_Bank_IT.cer
在XCA中选中服务端证书,点击“导出”按钮,选择导出DER格式的证书,用于客户端(如浏览器)安装或自动下载。
再点击一次“导出”按钮,选择导出p12格式密钥库,包括证书链和私钥,用作服务器端(如Tomcat)的密钥库:
参见5.3节
参见5.3节
在XCA中选中客户端证书,点击“导出”按钮,选择导出DER格式的证书,用于服务器(如Tomcat)安装可信证书。
再点击一次“导出”按钮,选择导出p12格式密钥库,包括证书链和私钥,用作客户端(浏览器)密钥导入:
参见5.3节
参见5.3节
**证书吊销列表(Certificate Revocation List,CRL)**一个被签署的列表,它指定了一套证书发布者认为无效的证书。除了普通CRL外,还定义了一些特殊的CRL类型用于覆盖特殊领域的CRL。
CRL一定是被CA所签署的,可以使用与签发证书相同的私钥,也可以使用专门的CRL签发私钥。CRL中包含了被吊销证书的序列号。
证书具有一个指定的寿命,但CA可通过称为证书吊销的过程来缩短这一寿命。CA发布一个证书吊销列表 (CRL),列出被认为不能再使用的证书的序列号。CRL 指定的寿命通常比证书指定的寿命短得多。CA也可以在CRL中加入证书被吊销的理由。它还可以加入被认为这种状态改变所适用的起始日期。
可将下列情况指定为吊销证书的理由:
由CA吊销证书意味着,CA在证书正常到期之前撤销其允许使用该密钥对的有关声明。在吊销的证书到期之后,CRL 中的有关条目被删除,以缩短CRL列表的大小。
在验证签名期间,应用程序可以检查CRL,以确定给定证书和密钥对是否仍然可信(有些应用程序使用 CryptoAPI 中的 Microsoft 证书链验证 API 来完成此任务)。如果不可信,应用程序可以判断吊销的理由或日期对使用有疑问证书是否有影响。如果该证书被用来验证签名,且签名的日期早于CA吊销该证书的日期,那么该签名仍被认为是有效的。
应用程序获得CRL之后,由客户机缓存CRL,在它到期之前客户机将一直使用它。如果CA发布了新的CRL,拥有有效CRL的应用程序并不使用新的CRL,直到应用程序拥有的CRL到期为止。
公钥证书中会写出该证书的CA中心CRL地址。
证书涉及很多编码规范,持久化到文件后,一般以不同的文件名区分不同的编码格式。
ASN.1(Abstract Syntax Notation dotone),抽象语法标记1。是定义抽象数据类型形式的标准,描绘了与任何表示数据的编码技术无关的通用数据结构。抽象语法使得人们能够定义数据类型,并指明这些类型的值。抽象语法只描述数据的结构形式,与具体的编码格式无关,同时也不涉及这些数据结构在计算机内如何存放。
X.690就是一个ITU-T的标准,它里面包含了一些对ASN.1进行编码的规则。
X.690主要包含了Basic Encoding Rules (BER),Canonical Encoding Rules (CER)和Distinguished Encoding Rules (DER)这三种编码规则。
证书数据需要存储和交换,需要生成证书文件,就会涉及到加密和编码。
X.509规定多种常用的证书文件扩展名。不过其中的一些还用于其它用途,就是说具有这个扩展名的文件可能并不是证书,比如说可能只是保存了私钥。
PEM(Privacy-Enhanced Mail,隐私增强邮件)是一种容器格式,可以将DER编码的证书再进行Base64编码后的数据存放在证书证书文件中,除了证书,还支持证书链,私钥。
PKCS(The Public-Key Cryptography Standards )是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。
文件扩展名 | 编码规则 | 数据格式 | 内容 | 样例 |
---|---|---|---|---|
.der | PKCS#10 | 二进制 | CSR | |
.der | DER public | 二进制 | 公钥 | |
.der | DER private | 二进制 | 私钥明文 | |
.der | DER | 二进制 | 单个证书 | |
.cer | DER | 二进制 | 单个证书 | |
.crt | PEM(DER) | 文本 + Base64 | 单个证书 | -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIJAP7FqyVU8c4aMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD … … uw== -----END CERTIFICATE----- |
.pub | SSH2 | 文本 + BASE64 | 公钥 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwwVYTaNkAoTTVPJebRYGizdNwluYZJQ/TpPSGPj2rGBZ2Fws6oCaKjUs2xasCcsejS+9XCVcHFbOei3NGKPYCZF0y/zZswahm+n15Uqi5QiIKV0Z9LO0vkYoc/z2DqF+ghHOidmJoFGE6xPQsh6qmJ7Z528W8GoviAVedSDDAB4wx+vEsTfQlBlVtawbFLJM9nv5Zv0TN+n19OfSEXYi4b391xRha0RJpTQe4RT3XaGtdFcoB5r+02nrJd8pAWWKEVWVPFKSOtNAEsv714ojdQe8PH1Vxfk3wKPzeSGkgpMRcrJu5F52lIxls+kDIamxFTucxLhGc9aEr5Ovc+Nfh |
.p7b | PKCS#7 | 二进制 | 单个证书 | |
.p7b | PKCS#7 chain | 二进制 | 整个证书链 | |
.p7b | PKCS#7 unrevoked | 二进制 | 所有未回收的证书 | |
.p7b | PKCS#7 all | 二进制 | 所有证书 | |
.p7b | PKCS#7 all | 二进制 | 所有证书 | |
.pk8 | PKCS#8 | 文本 + BASE64 | 私钥明文 | -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDwwVYTaNkAoTTV … … Z8x0ItwuGWLTqanPqsb34cI= -----END PRIVATE KEY----- |
.pk8 | PKCS#8 encrypted | 二进制 | 私钥密文 | |
.p12 | PKCS#12 | 二进制 | 单个证书,私钥密文 | |
.p12 | PKCS#12 chain | 二进制 | 整个证书链,私钥密文 | |
.pem | PEM(PKCS#10) | 文本 + BASE64 | CSR | -----BEGIN CERTIFICATE REQUEST----- MIIC1zCCAb8CAQAwgZExCzAJBgNVBAYTAkNOMRAwDgYDVQQIEwdTaGFubnhpMQ0w … … IeQNwGABoS7ah4U= -----END CERTIFICATE REQUEST----- |
.pem | PEM | 文本 + BASE64 | CRL | -----BEGIN X509 CRL----- MIIB4jCBywIBATANBgkqhkiG9w0BAQsFADCBhzELMAkGA1UEBhMCQ04xEDAOBgNV … … uGkHOM+H -----END X509 CRL----- |
.pem | PEM public | 文本 + BASE64 | 公钥 | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8MFWE2jZAKE01TyXm0WB … … 4QIDAQAB -----END PUBLIC KEY----- |
.pem | PEM private | 文本 + BASE64 | 只包含私钥明文 | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA2GzOjLTUdts7x4SUuGShf9usFwkX6V72H2ucR+z9sQPkKZyP … … PvIv6XUFxBUUwRgPC1+UJfdpmIU44uGve/Tf9TRAvxgHVzTezu0whg== -----END RSA PRIVATE KEY----- |
.pem | PEM + key | 文本 + BASE64 | 单个证书,私钥明文 | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA2GzOjLTUdts7x4SUuGShf9usFwkX6V72H2ucR+z9sQPkKZyP … … PvIv6XUFxBUUwRgPC1+UJfdpmIU44uGve/Tf9TRAvxgHVzTezu0whg== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIJAP7FqyVU8c4aMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD … … uw== -----END CERTIFICATE----- |
.pem | PEM(PKCS#8) | 文本 + BASE64 | 单个证书,私钥密文 | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA2GzOjLTUdts7x4SUuGShf9usFwkX6V72H2ucR+z9sQPkKZyP … … PvIv6XUFxBUUwRgPC1+UJfdpmIU44uGve/Tf9TRAvxgHVzTezu0whg== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIJAP7FqyVU8c4aMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD … … uw== -----END CERTIFICATE----- |
.pem | PEM unrevoked | 文本 + BASE64 | 所有未回收的证书 | -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIJAP7FqyVU8c4aMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD … … uw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIJAP7FqyVU8c4aMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD … … uw== -----END CERTIFICATE----- |
.pem | PEM chain | 文本 + BASE64 | 用文本拼接的方式包含所有证书 | -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIJAP7FqyVU8c4aMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD … … uw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIJAP7FqyVU8c4aMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD … … uw== -----END CERTIFICATE----- |
.key | PEM private | 文本 + BASE64 | 只包含私钥明文 | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA2GzOjLTUdts7x4SUuGShf9usFwkX6V72H2ucR+z9sQPkKZyP … … PvIv6XUFxBUUwRgPC1+UJfdpmIU44uGve/Tf9TRAvxgHVzTezu0whg== -----END RSA PRIVATE KEY----- |
.pfx | PKCS#12 | 二进制 | 同PKCS#12 |
HTTP 由于是明文传输,主要存在三大风险:窃听风险、篡改风险、冒充风险。
HTTPS 就是为了解决上述三个风险而生的,一般我们认为安全的通信需要包括以下四个原则: 机密性、完整性,身份认证,不可否认。
HTTPS (全称:Hypertext Transfer Protocol Secure),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。HTTPS 在HTTP 的基础下加入SSL,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面 。
TLS利用密钥算法在互联网上提供端点身份认证与通讯保密,其基础是公钥基础设施(public key infrastructure,PKI),证书为TLS协议中加密算法的公钥的安全传输提供了解决方案。不过在实现的典型例子中,只有网络服务者被可靠身份验证(单向认证),而其客户端(双向认证)则不一定。这是因为公钥基础设施普遍商业运营,证书通常需要付费购买。
在智能手机普及之前,银行如何实现HTTPs双向认证的 ?通常会提供给客户一个U盾,只有在插入U盾的电脑上才能进行转账操作。其实原理也是在U盾中添加了密钥库和和客户端证书,用来认证客户身份。但这种方案成本很高,每一个客户都需要一个独立的U盾。
下面我们以一个实际的Springboot项目的例子来看如何配置双向认证的HTTPS连接。
首先创建一个空的SpringBoot项目。
总结一下涉及到的所有证书和密钥库:
文件 | 描述 | 安装位置 |
---|---|---|
HF_Bank_IT.cer | CA根证书,用做客户端证书HF_Commercial_Bank_client.cer和服务端证书HF_Commercial_Bank.cer的认证 | 需要安装到浏览器受信密钥库,服务端Tomcat受信密钥库 |
HF_Commercial_Bank_client.cer | 客户端证书,会被浏览器随请求发送到服务端认证客户端 | 不用安装或者安装到服务端受信密钥库 |
HF_Commercial_Bank_client.p12 | 客户端密钥库,保存客户端证书和私钥 | 需要安装到浏览器密钥库 |
HF_Commercial_Bank.cer | 会被Tomcat随请求发送给浏览器认证服务端 | 不需要安装 |
HF_Commercial_Bank.p12 | 服务端密钥库 | 需要在Tomcat中配置,指定为Tomcat的密钥库 |
服务端用来CA的公钥来验证客户端证书的签名。
运行如下命令:
C:\Users\Administrator\Desktop>keytool -import -alias hf-root-ca -file HF_Bank_IT.cer -keystore trust-key-store.jks
输入密钥库口令:
所有者: [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN
发布者: [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN
序列号: 6b87345687a86b10
有效期为 Sat Jan 14 11:28:00 CST 2023 至 Fri Jan 14 11:28:00 CST 2033
证书指纹:
MD5: 2A:59:C2:10:5C:20:4B:26:CE:D7:95:09:F4:87:08:AC
SHA1: 4C:85:20:BF:43:0A:15:9F:CA:98:1B:7C:F3:2A:14:D9:DC:A3:6E:BE
SHA256: 73:3A:D7:BA:32:65:A7:C5:9C:35:92:E0:14:DE:E5:F8:D7:33:59:CB:DB:72:97:F4:C9:85:9B:D9:9B:E9:8B:58
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
扩展:
#1: ObjectId: 2.16.840.1.113730.1.13 Criticality=false
0000: 16 0F 78 63 61 20 63 65 72 74 69 66 69 63 61 74 ..xca certificat
0010: 65 e
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
#3: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
Key_CertSign
Crl_Sign
]
#4: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
NetscapeCertType [
SSL CA
S/MIME CA
Object Signing CA]
#5: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 4C BD 22 CE 6E F2 3F D7 22 FE F1 D8 41 83 F5 DA L.".n.?."...A...
0010: 16 1C 2B 4E ..+N
]
]
是否信任此证书? [否]: y
证书已添加到密钥库中
C:\Users\Administrator\Desktop>
这一步是将客户端证书HF_Commercial_Bank_client.cer安装到服务器的信任密钥库中。
在控制台运行如下命令:
C:\Users\Administrator\Desktop>keytool -import -alias kt-client-ca -file HF_Commercial_Bank_client.cer -keystore trust-key-store.jks
输入密钥库口令:
再次输入新口令:
所有者: [email protected], CN=www.hkt.com, OU=Hong Kong Telecom IT, O=Hong Kong Telecom, L=HongKong, ST=HongKong, C=CN
发布者: [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN
序列号: fec5ab2554f1ce1a
有效期为 Sat Jan 14 15:29:00 CST 2023 至 Sun Jan 14 15:29:00 CST 2024
证书指纹:
MD5: D4:D4:AD:52:B7:49:BD:C3:FF:E0:DC:F2:22:2B:03:A0
SHA1: CE:9F:CA:53:00:8F:54:27:6A:35:76:51:85:E8:91:40:27:62:B5:9C
SHA256: 78:8E:5E:79:EE:D8:1F:A8:65:87:78:2D:77:42:5F:6C:E8:B6:DD:CD:C2:FF:21:8D:13:BA:82:5F:AF:EA:13:61
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
扩展:
#1: ObjectId: 2.16.840.1.113730.1.13 Criticality=false
0000: 16 0F 78 63 61 20 63 65 72 74 69 66 69 63 61 74 ..xca certificat
0010: 65 e
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]
#3: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
DigitalSignature
Key_Encipherment
Data_Encipherment
]
#4: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
NetscapeCertType [
SSL client
S/MIME
]
#5: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: A6 1E AB 35 97 74 2E 50 BB 0D 7D 2C A9 D3 18 1A ...5.t.P...,....
0010: 26 71 72 4B &qrK
]
]
是否信任此证书? [否]: y
证书已添加到密钥库中
C:\Users\Administrator\Desktop>
这条命令做了两件事情:
完毕后可以运行如下命令查看密钥库中的证书,确认安装成功。现在信任密钥库中应该有两个证书。
C:\Users\Administrator\Desktop>keytool -list -v -keystore trust-key-store.jks
输入密钥库口令:
密钥库类型: jks
密钥库提供方: SUN
您的密钥库包含 2 个条目
别名: kt-client-ca
创建日期: 2023-1-14
条目类型: trustedCertEntry
所有者: [email protected], CN=www.hkt.com, OU=Hong Kong Telecom IT, O=Hong Kong Telecom, L=HongKong, ST=HongKong, C=CN
发布者: [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN
序列号: fec5ab2554f1ce1a
有效期为 Sat Jan 14 15:29:00 CST 2023 至 Sun Jan 14 15:29:00 CST 2024
证书指纹:
MD5: D4:D4:AD:52:B7:49:BD:C3:FF:E0:DC:F2:22:2B:03:A0
SHA1: CE:9F:CA:53:00:8F:54:27:6A:35:76:51:85:E8:91:40:27:62:B5:9C
SHA256: 78:8E:5E:79:EE:D8:1F:A8:65:87:78:2D:77:42:5F:6C:E8:B6:DD:CD:C2:FF:21:8D:13:BA:82:5F:AF:EA:13:61
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
扩展:
#1: ObjectId: 2.16.840.1.113730.1.13 Criticality=false
0000: 16 0F 78 63 61 20 63 65 72 74 69 66 69 63 61 74 ..xca certificat
0010: 65 e
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]
#3: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
DigitalSignature
Key_Encipherment
Data_Encipherment
]
#4: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
NetscapeCertType [
SSL client
S/MIME
]
#5: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: A6 1E AB 35 97 74 2E 50 BB 0D 7D 2C A9 D3 18 1A ...5.t.P...,....
0010: 26 71 72 4B &qrK
]
]
*******************************************
*******************************************
别名: hf-root-ca
创建日期: 2023-1-14
条目类型: trustedCertEntry
所有者: [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN
发布者: [email protected], CN=www.hf.com, OU=HF Bank IT, O=HF Bank, L=Xian, ST=Shannxi, C=CN
序列号: 6b87345687a86b10
有效期为 Sat Jan 14 11:28:00 CST 2023 至 Fri Jan 14 11:28:00 CST 2033
证书指纹:
MD5: 2A:59:C2:10:5C:20:4B:26:CE:D7:95:09:F4:87:08:AC
SHA1: 4C:85:20:BF:43:0A:15:9F:CA:98:1B:7C:F3:2A:14:D9:DC:A3:6E:BE
SHA256: 73:3A:D7:BA:32:65:A7:C5:9C:35:92:E0:14:DE:E5:F8:D7:33:59:CB:DB:72:97:F4:C9:85:9B:D9:9B:E9:8B:58
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
扩展:
#1: ObjectId: 2.16.840.1.113730.1.13 Criticality=false
0000: 16 0F 78 63 61 20 63 65 72 74 69 66 69 63 61 74 ..xca certificat
0010: 65 e
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
#3: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
Key_CertSign
Crl_Sign
]
#4: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
NetscapeCertType [
SSL CA
S/MIME CA
Object Signing CA]
#5: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 4C BD 22 CE 6E F2 3F D7 22 FE F1 D8 41 83 F5 DA L.".n.?."...A...
0010: 16 1C 2B 4E ..+N
]
]
*******************************************
*******************************************
C:\Users\Administrator\Desktop>
新建文件夹:src\main\resources\certs,将密钥库拷贝到文件夹下:
src\main\resources\certs\HF_Commercial_Bank.p12
src\main\resources\certs\trust-key-store.jks
添加HTTP协议配置:application-http.yml,内容如下:
server:
port: 8080
添加单向HTTPS协议配置:application-one-way-https.yml,内容如下:
server:
port: 8443
ssl:
# 单向认证,浏览器认证服务端
enabled: true
key-store: classpath:certs/HF_Commercial_Bank.p12
key-store-password: 123456
keyStoreType: PKCS12
添加双向HTTPS协议配置:application-two-way-https.yml,内容如下:
server:
port: 8443
ssl:
# 单向认证,浏览器认证服务端
enabled: true
key-store: classpath:certs/HF_Commercial_Bank.p12
key-store-password: 123456
keyStoreType: PKCS12
# 双向认证,服务端认证浏览器,需要配置信任客户端证书库,里面安装了为客户端生成的.cer证书
client-auth: need
trust-store: classpath:certs/trust-key-store.jks
trust-store-password: 123456
trust-store-type: JKS
修改全局配置文件:application.yml,激活two-way-https profile,内容如下:
spring:
application:
name: springboot-demo-2-way-https
profiles:
active: two-way-https
如果是独立部署的Tomcat服务,需要修改server.xml文件:
单向认证:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="E:/HF_Commercial_Bank.p12" keystorePass="123456"
/>
双向认证:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS" keystoreFile="E:/HF_Commercial_Bank.p12" keystorePass="123456" truststoreFile="E:/trust-key-store.jks" truststorePass="123456"/>
这个Controller提供了测试调用的/health接口,并打印出客户端携带的证书信息。
package com.qupneg.java.demo.springboot.twoway.https;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.security.cert.X509Certificate;
@RestController
public class HealthController {
@GetMapping(value="/health")
public String health(HttpServletRequest request) {
X509Certificate[] certs = (X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");
String certInfo = "";
if(certs != null) {
X509Certificate gaX509Cert = certs[0];
String dn = gaX509Cert.getSubjectDN().toString();
System.out.println("Certificate:" + dn);
certInfo = gaX509Cert.toString();
}
return "up.\r\nSent request with the cert info: \r\n" + certInfo;
}
}
这个类将客户端HTTP请求重定向为HTTPS请求,禁用HTTP协议的一种办法。
还有一种更推荐的方案:HSTS(HTTP Strict Transport Security),但是需要浏览器支持,老版本的浏览器可能不支持。服务端收到HTTP请求后,返回一个response header:
Strict-Transport-Security: max-age=31536000; includeSubDomains
给浏览器,浏览器收到后将请求转换为HTTPS再发送一次。
package com.qupneg.java.demo.springboot.twoway.https;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedirectConfiguration {
/**
* http重定向到https
* @return
*/
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint constraint = new SecurityConstraint();
constraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
constraint.addCollection(collection);
context.addConstraint(constraint);
}
};
tomcat.addAdditionalTomcatConnectors(httpConnector());
return tomcat;
}
@Bean
public Connector httpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
//Connector监听的http的端口号
connector.setPort(8080);
connector.setSecure(false);
//监听到http的端口号后转向到的https的端口号
connector.setRedirectPort(8443);
return connector;
}
}
这一步是模仿权威CA根证书,将自签名CA根证书倒入客户端系统,成为可信任的CA根证书。
在Windows中双击证书文件:HF_Bank_IT.cer进行安装,安装完成后在浏览器的证书管理中可以看到已添加到受信列表:
这一步是安装客户端证书和私钥到客户端系统。
在Windows中双击密钥库文件:HF_Commercial_Bank_client.p12进行安装,安装完成后在浏览器的证书管理中可以看到已添加到个人证书:
如果缺少了以上步骤,就会在浏览器中看到客户端证书校验失败的错误。
构建并运行程序,访问链接:https://localhost:8443/health,浏览器会提示选择认证的证书。
选择安装的客户端证书,点击“确定”按钮,成功收回相应,打印出客户端证书的详情:
至此,双向HTTPS部署成功。