Java加解密(八)数字证书

目录

  • 数字证书
    • 1 定义
    • 2 证书组成结构
    • 3 公钥基础设施(PKI)
      • 3.1 PKI的组成
      • 3.2 PKI的相关标准
      • 3.3 信任模型
    • 4 证书的应用场景
    • 5 证书链
    • 6 生成证书
      • 6.1 通过CA生成可信证书
        • 6.1.1 国际权威认证机构
        • 6.1.2 生成CSR
          • 6.1.2.1 使用XCA生成CSR
          • 6.1.2.2 使用OpenSSL生成CSR
          • 6.1.2.3 使用Keytool生成CSR文件
      • 6.2 生成自签名根证书
        • 6.2.1 使用CXA生成自签名根证书
        • 6.2.2 使用OpenSSL生成自签名根证书
        • 6.2.3 使用Keytool生成自签名根证书
      • 6.3 用自签名根证书签发用户证书
        • 6.3.1 使用XCA签发用户证书
        • 6.3.2 服务端证书与客户端证书
        • 6.3.3 使用OpenSSL签发用户证书
        • 6.3.4 使用Keytool签发用户证书
      • 6.4 导出证书和密钥库
        • 6.4.1 导出自签名CA根证书
          • 6.4.1.1 使用XCA
        • 6.4.1.2 使用OpenSSL
        • 6.4.1.3 使用Keytool
        • 6.4.2 导出服务端证书和密钥库
          • 6.4.2.1 使用XCA导出服务端证书和密钥库
          • 6.4.2.2 使用OpenSSL导出服务端证书和密钥库
          • 6.4.2.3 使用Keytool导出服务端证书和密钥库
        • 6.4.3 导出客户端证书和密钥库
          • 6.4.3.1 使用XCA导出客户端证书和密钥库
          • 6.4.3.2 使用OpenSSL导出客户端证书和密钥库
          • 6.4.3.3 使用Keytool导出客户端证书和密钥库
    • 7 作废证书
    • 8 证书的存储格式
      • 8.1 证书的编码规范
        • ASN.1(Abstract Syntax Notation dotone),抽象语法标记1。
        • X.690
      • 8.2 证书文件格式
    • 9 部署HTTPS双向认证
      • 9.1 创建SpringBoot的项目
      • 9.2 部署HTTPS双向认证
        • 9.2.1 部署服务端
          • 1 导入CA根证书到信任密钥库(trust keystore)
          • 2 导入客户端证书到信任密钥库(trust keystore)
          • 3 添加密钥库文件
          • 4 添加HTTPS profile
          • 5 添加Controller
          • 6 添加Redirec配置
        • 9.2.2 部署客户端
          • 1 安装CA根证书
          • 2 安装客户端密钥库
        • 9.2.3 运行程序

数字证书

1 定义

数字证书(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 数字签名

2 证书组成结构

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数字证书结构如下:

  • 公钥算法
  • 主体公钥
  • 此日期前无效
  • 此日期后无效
  • 版本号
  • 序列号
  • 签名算法
  • 颁发者
  • 证书有效期
  • 主体
  • 主体公钥信息
  • 颁发者唯一身份信息(可选项)
  • 主体唯一身份信息(可选项)
  • 扩展信息(可选项)
  • 证书签名算法
  • 数字签名
  • 所有扩展都有一个ID,由object identifier来表达.它是一个集合,并且有一个标记用与指示这个扩展是不是决定性的。证书使用时,如果发现一份证书带有决定性标记的扩展,而这个系统并不清楚该扩展的用途,那么要拒绝使用它。但对于非决定性的扩展,不认识可以予以忽略。RFC 1422给出了v1的证书结构 ITU-T在v2里增加了颁发者和主体唯一标识符,从而可以在一段时间后可以重用。重用的一个例子是当一个CA破产了,它的名称也在公共列表里清除掉了,一段时间之后另一个CA可以用相同的名称来注册,即使它与之前的并没有任何瓜葛。不过IETF并不建议重用同名注册。另外v2在Internet也没有多大范围的使用。 v3引入了扩展。CA使用扩展来发布一份特定使用目的的证书(比如说仅用于代码签名) 所有的版本中,同一个CA颁发的证书序列号都必须是唯一的。

3 公钥基础设施(PKI)

仅有证书规范还不足以支持公钥的实际运行,我们还需要很多其他的规范,例如证书应该由谁来颁发,如何颁发,私钥泄漏时应该如何作废证书,计算机之间的数据交换应采用怎样的格式等。

**公钥基础设施(Public-Key Infrastructure, PKI)**是为了能够更有效的运用公钥而制定的一系列规范和规格的总称。PKI只是一个总称,而并非指某一个单独的规范或规格。

PKI是一个包括硬件、软件、人员、策略和规程的集合,用来实现基于公钥密码体制的密钥和证书的产生、管理、存储、分发和撤销等功能。

PKI体系是计算机软硬件、权威机构及应用系统的结合。它为实施电子商务、电子政务、办公自动化等提供了基本的安全服务,从而使那些彼此不认识或距离很远的用户能通过信任链安全地交流。

3.1 PKI的组成

一个典型的PKI系统包括PKI安全策略、软硬件系统、证书机构CA、注册机构RA、证书发布系统和PKI应用等。

  1. PKI安全策略
    建立和定义了一个组织信息安全方面的指导方针,同时也定义了密码系统使用的处理方法和原则。它包括一个组织怎样处理密钥和有价值的信息,根据风险的级别定义安全控制的级别。
  2. 证书机构CA
    证书机构CA是PKI的信任基础,它管理公钥的整个生命周期,其作用包括:发放证书、规定证书的有效期和通过发布证书废除列表(CRL)确保必要时可以废除证书。
  3. 注册机构RA
    注册机构RA提供用户和CA之间的一个接口,它获取并认证用户的身份,向CA提出证书请求。它主要完成收集用户信息和确认用户身份的功能。这里指的用户,是指将要向认证中心(即CA)申请数字证书的客户,可以是个人,也可以是集团或团体、某政府机构等。注册管理一般由一个独立的注册机构(即RA)来承担。它接受用户的注册申请,审查用户的申请资格,并决定是否同意CA给其签发数字证书。注册机构并不给用户签发证书,而只是对用户进行资格审查。因此,RA可以设置在直接面对客户的业务部门,如银行的营业部、机构认识部门等。当然,对于一个规模较小的PKI应用系统来说,可把注册管理的职能由认证中心CA来完成,而不设立独立运行的RA。但这并不是取消了PKI的注册功能,而只是将其作为CA的一项功能而已。PKI国际标准推荐由一个独立的RA来完成注册管理的任务,可以增强应用系统的安全。
  4. 证书发布系统
    证书发布系统负责证书的发放,如可以通过用户自己,或是通过目录服务器发放。目录服务器可以是一个组织中现存的,也可以是PKI方案中提供的。
  5. PKI的应用
    PKI的应用非常广泛,包括应用在web服务器和浏览器之间的通信、电子邮件、电子数据交换(EDI)、在Internet上的信用卡交易和虚拟私有网(VPN)等。

3.2 PKI的相关标准

  • ASN.1基本编码规则的规范——X.209(1988)
    ASN.1是描述在网络上传输信息格式的标准方法。它有两部分:第一部分(ISO 8824/ITU X.208)描述信息内的数据、数据类型及序列格式-也就是数据的语法;第二部分(ISO8825/ITU X.209)描述如何将各部分数据组成消息,也就是数据的基本编码规则。这两个协议除了在PKI体系中被应用外,还被广泛应用于通信和计算机的其他领域。
  • 目录服务系统标准——X.500(1993)
    X.500是一套已经被国际标准化组织(ISO)接受的目录服务系统标准,它定义了一个机构如何在全局范围内共享其名字和与之相关的对象。X.500是层次性的.其中的管理域(机构、分支、部门和工作组)可以提供这些域内的用户和资源信息。在PKI体系中,X.500被用来标识一个实体。该实体可以是机构、组织、个人或一台服务器。X.500被认为是实现目录服务的最佳途径,但X.500的实现需要较大的投资,并且比其他方式速度慢;但其优势是具有信息模型、多功能和开放性。 [3]
  • LDAP轻量级目录访问协议一LDAP V3
    LDAP规范(RFCl487)简化了笨重的X.500目录访问协议,并且在功能性、数据表示、编码和传输方面部进行了相应的修改,1997年.LDAP第3版本成为互联网标准。LDAP V3已经在PKI体系中被广泛应用于证书信息发布、CRI。信息发布、CA政策以及与信息发布相关的各个方面。
  • 数字证书标准 X.509(1 993)
    X.5(19是南国际电信联盟(ITU—T)制定的数字证书标准、在X.500确保用户名称唯一性的基础上.X.509为X.500用户名称提供了通信实体的鉴别机制并规定了实体鉴别过程中广泛适用的证书语法和数据接口。X.509的最初版本公布于l 988年,由用户公开密钥和用户标识符组成此外还包括版本号、证书序列号、CA标识符、签名算法标识、签发者名称、证书有效期等信息。这一标准的最新版本是X.509 V3,该版数字证书提供了一个扩展信息字段.用来提供更多的灵活性及特殊应用环境下所需的信息传送。
  • OCSP在线证二拉状态协议
    OCSP(OnIine Certificate Status Protocol)是IETF颁布的用于检查数字证书在某一交易时刻是否仍然有效的标准。该标准提供给PKI用户一条方便快捷的数字证书状态查询通道.使PKI体系能够更有效、更安全地在各个领域中被广泛应用。
  • PKCS系列标准
    PKCS是南美RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。

3.3 信任模型

实际网络环境中不可能只有一个CA.多个认证机构之间的信任关系必须保证原有的PKI户不必依赖和信任专一的CA,否则将无法进行扩展、管理和包含。 信任模型建立的目的是确保一个认证机构签发的证书能够被另一个认证机构的用户所信任。常见的信任模型包括以下四种:

  1. 严格层次信任模型
    严格层次信任模型是一个以主从CA关系建立的分级PKl结构,可以描绘为一棵倒转的树,在这棵树上,根代表一个对整个PKI域内的所有实体都有特别意义的CA:根CA,在根CA的下面是多层子CA,与非CA的PKI实体相对应的树叶通常被称作终端用户。
    在严格层次信任模型中,上层CA为下层颁发证书,所有的实体都信任根CA,以根CA作为信任点。信任关系是单向的,上层CA可以而且必须认证下层CA,但下层CA不能认证上层CA,根CA通常不直接为终端用户颁发证书而只为子CA颁发证书。两个不同的终端用户进行交互时,双方都提供自己的证书和数字签名,通过根CA来对证书进行有效性和真实性的认证。只要找到一条从根CA到一个证书的认证路径,就可以实现对证书的验证。
  2. 分布式信任模型
    与严格层次信任模型中的所有实体都信任唯一CA相反,分布式信任模型把信任分布在两个或多个CA上,在分布式信任模型中,CA间存在着交叉认证。因为存在多个信任点,单个CA安全性的削弱不会影响到整个PKI。因此该信任模型具有更好的灵活性但其路径发现比较困难,因为从终端用户到信任点建立证书的路径是不确定的。
  3. 以用户为中心的信任模型
    在以用户为中心的信任模型中,每个用户自己决定信任哪些证书和拒绝哪些证书,没有可信的第三方作为CA,用户就是自己的根CA。通常,用户的信任对象一般为关系密切的用户。
    以用户为中心的信任模型具有安全性高和用户可控性强的优点.但是其使其范闱较小,因为要依赖用户自身的行为和决策能力,这在技术水平较高的群体中是可行的,而在一般的群体中是不现实的。
  4. 交叉认证模型
    交叉认证是一种把以前无关的CA连接在一起的机制.可以使得它们各自终端用户之间的安全通信成为可能.有两种类型的交叉认证:域内交叉认证和域间交叉认证。

4 证书的应用场景

一个通用的场景:Alice想要给Bob发消息,但是首先要确认Bob是身份是可信的。所以Alice首先拿到Bob的证书(从哪里取到证书,见第二张图),并通过认证机构Trent验证Bob证书的合法性。如果认证成功,就用Bob的公钥加密数据,发送给Bob。
Java加解密(八)数字证书_第1张图片
Bob首先在认证机构注册公钥,认证机构将生成的证书放在仓库(例如基于LDAP V3规范的服务器)中,供用户下载,比如Alice。
Java加解密(八)数字证书_第2张图片

5 证书链

上以节提到认证机构的分层信任模型,根CA,中间CA和终端用户。

对应到证书上,证书也是分层级的,CA根证书,中间证书,用户证书,并且不同层级的证书形成了一个信任链。

**证书链(也就是RFC 5280里的证书路径)是从终端用户证书后跟着一系列的CA证书,而通常最后一个是自签名证书(CA根证书),并且有如下关系:

  • 在证书链上除最后一个证书外,证书颁发者等于其后一个证书的持有者。
  • 除了最后一个证书,每个证书都是由其后的一个证书签名的。
  • 最后的证书是信任主题,由于是通过可信过程得到的,你可以信任它。

证书链用于检查目标证书(证书链里的第一个证书,用户证书)里的公钥及其它数据是否属于其持有者。检查是这么做的,用证书链中的下一个证书的公钥来验证它的签名,一直检查到证书链的尾端,如果所有验证都成功通过,那个这个证书就是可信的。

例如我们可以看到,百度的证书所在证书链长度为3,是由中间证书签发的。
Java加解密(八)数字证书_第3张图片
如图所示就是一个由根证书,中间证书,用户证书等组成一条完整证书信任链。只有当整个证书信任链上的各个证书都有效时,浏览器才会认定当前颁发给用户的证书是有效和受信任的。而证书链文件是指除了用户证书以外中间证书和根证书组成的证书文件称之为证书链文件。证书链文件是证书部署和验证证书是否可信环节中最重要的组成部分。

  • 根证书
    是受信任CA证书颁发机构给自己颁发的证书,是信任链的起始点。浏览器判断根证书是否受信任主要是通过检索浏览器的根证书库可信任列表里是否存在。如果存在浏览器就会信任该根证书。目前有的浏览器会自建根证书库,例如火狐浏览器,有的浏览器会使用其他浏览器的根证书库或者调用操作系统的根证书库,例如谷歌浏览器。根证书信息查看可以通过点击根证书后查看证书信息后显示根证书的颁发者以及有效期等信息。

  • 中间证书
    是根证书颁发机构CA对中间证书颁发机构的公钥进行数字签名得到的证书。中间证书的作用主要是为了保护根证书。因为如果直接采用根证书签发证书,一旦发生根证书泄露,将造成极大的安全问题。中间证书可以不止一个,目前我们经常看到有两级中间证书的,原则上中间证书层数越多,根证书越安全。但是一般情况下最多也不超过2级。

  • 用户证书
    是由中间证书CA签发给用户的证书。用户证书由中间证书证明可信。用户证书是浏览器上实际体现和使用的证书。用户证书可以通过点击小锁后查看到该证书颁发给哪个域名或者ip,证书有效期,颁发机构等信息。

根证书签发中间证书,中间证书签发用户证书,用户证书就无法再签发证书了。

认证时先从受信列表中查询根证书,然后用根证书认证证中间证书,最后用中间证书的公钥认证用户证书。

所以说,客户端和服务端在进行网络通信时,不止会发送证书,证书链也会一起发送,这样才能做到逐级认证。

6 生成证书

通常有以下几种方式来生成证书:

6.1 通过CA生成可信证书

6.1.1 国际权威认证机构

以下是国际权威数字证书颁发认证机构的“三巨头”:

  • VeriSign:http://www.verisign.com
  • GeoTrust:http://www.geotrust.com/
  • Thawte:http://www.thawte.com
    其中,应用最为广泛的是VeriSign签发的电子商务数字证书。

除此之外还有:
DigiCert: https://www.digicert.com/

通常,这种由国际权威数字证书颁发认证机构颁发的数字证书需要向用户收取昂贵的申请和维护费用。但并不是所有的国际权威数字证书颁发认证机构都收费,CAcert:http://www.cacert.org 就是一个免费的数字证书颁发国际组织。随着用户群的增大和颁发手段的可信性,这种免费的数字证书可信度也越来越高。

6.1.2 生成CSR

申请数字证书之前,您必须先生成证书的密钥文件和CSR文件。CSR文件是您的公钥证书原始文件,包含了您的服务器信息和您的单位信息,需要提交给CA认证中心进行审核。

CSR的全称是证书签发请求,即证书请求文件,也就是证书申请者在申请数字证书时由CSP(加密服务提供者)在生成私钥的同时也生成证书请求文件,证书申请者只要把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件,也就是颁发给用户的证书。

6.1.2.1 使用XCA生成CSR

XCA(X Certificate and key management) 是作为证书和密钥存储,以及作为签发证书的签名应用程序,是一个开源的工具,底层还是基于openssl的类库和API的。
首先需要下载并安装工具,官网地址为:https://www.hohnstaedt.de/xca/index.php/download

安装完成后,首先创建数据库,然后切换到CSR页签,点击“新建请求”按钮:
Java加解密(八)数字证书_第4张图片
假设我们要为HF银行的IT部门的网站申请SSL证书,填写申请者信息,并同时生成私钥:
公司:HF银行
部门:HF银行IT部门
网站域名:www.hf.com
Java加解密(八)数字证书_第5张图片
然后导出CSR文件:
Java加解密(八)数字证书_第6张图片

导出的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-----

还要导出私钥文件,用于以后的部署:
Java加解密(八)数字证书_第7张图片

私钥文件内容如下:

-----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的页面。
Java加解密(八)数字证书_第8张图片
申请证书的整个过程大致分为4个步骤:

  1. 首先注册成为网站会员然后登录。
  2. 点击右侧菜单“域名-新建”,注册CSR中填写的Common Name对应的网站域名,并选择管理员邮箱。
  3. 网站会发送验证邮件,需要登录邮箱确认才能激活设置的邮箱。
  4. 然后选择右侧菜单“服务器证书-新建”,将CSR内容黏贴到表单中,点击“提交”按钮。
  5. 网站验证成功后,生成证书。

拿到证书后,就可以与私钥一起来部署服务器了(后面的章节继续讨论)。

6.1.2.2 使用OpenSSL生成CSR

生成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  
6.1.2.3 使用Keytool生成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

6.2 生成自签名根证书

自签名证书是由不受信的CA机构颁发的数字证书,也就是自己签发的证书。与受信任的CA签发的传统数字证书不同,自签名证书是由一些公司或软件开发商创建、颁发和签名的。虽然自签名证书使用的是与X.509证书相同的加密密钥对架构,但是却缺少受信任第三方的验证。在颁发过程中缺乏独立验证会产生额外的风险,这就是为什么对于面向公众的网站和应用程序来说,自签名证书是不安全的。

自签名证书可以有许多不同的证书类型,包括SSL/TLS证书、S/MIME证书、代码签名证书等,其中最常见的证书类型是自签名SSL证书。与CA颁发的SSL证书不同,自签名证书通常指的是那些未经第三方验证,直接上传到私有公钥基础结构 (PKI) 的证书文件。

6.2.1 使用CXA生成自签名根证书

在XCA里选择“证书”标签页,点击“新建证书”按钮:
Java加解密(八)数字证书_第9张图片
创建自签名证书,并应用CA模板:
Java加解密(八)数字证书_第10张图片
切换到“持有者”页签,填写身份信息,并创建私钥:
Java加解密(八)数字证书_第11张图片
点击OK按钮生成自签名证书。

6.2.2 使用OpenSSL生成自签名根证书

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  

6.2.3 使用Keytool生成自签名根证书

keytool -export -alias hf-bank-it -keystore HF_Bank_IT.jks -rfc -file HF_Bank_IT.cer

6.3 用自签名根证书签发用户证书

我们已经创建了自己的根证书,就可以作为CA,签发自己的子证书了。

6.3.1 使用XCA签发用户证书

假设HF银行的商业银行部门的网站需要进行HTTPS的升级,需要IT部门用根证书签发一个子证书,首先商业银行分部需要创建一个CSR,并且生成私钥:
Java加解密(八)数字证书_第12张图片
然后我们选择新建一个证书,类型选择从CSR签发:
Java加解密(八)数字证书_第13张图片
证书生成成功后,我们现在拥有了一个2级的证书链,包含俩个证书:

  • CA根证书:自签名的CA证书
  • 用户证书:服务端证书

Java加解密(八)数字证书_第14张图片
银行业务安全第一,所以如果需要部署双向HTTPS认证,还需要生成一个客户端证书。

假如客户是香港电讯,首先,客户会生成一个CSR和私钥,CSR发给HF银行来签发证书,自己保存私钥。

CSR内容如下:
Java加解密(八)数字证书_第15张图片

打开XCA,我们用CA根证书签发一个客户端证书:
Java加解密(八)数字证书_第16张图片
最终,我们拥有了3张证书:
Java加解密(八)数字证书_第17张图片
到这里,所有证书签发完毕,下一步,需导出证书和密钥库。

6.3.2 服务端证书与客户端证书

部署HTTPS时,我们可以选择两种认证方案:

  1. 单向认证
    客户端认证服务端,客户端安装服务端的公钥证书,服务端持有私钥。这个公钥证书,就是服务端证书
  2. 双向认证
    客户端既要认证服务端,服务端也要认证客户端,服务端安装客户端的公钥证书,客户端持有私钥。这个公钥证书,就是客户端证书

6.3.3 使用OpenSSL签发用户证书

用户证书的生成步骤:
生成私钥(.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   

6.3.4 使用Keytool签发用户证书

服务端证书:

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

6.4 导出证书和密钥库

6.4.1 导出自签名CA根证书

6.4.1.1 使用XCA

在XCA中选中根证书,点击“导出”按钮,选择导出DER格式的证书,用户服务端和客户端安装,形成证书链。
Java加解密(八)数字证书_第18张图片

6.4.1.2 使用OpenSSL

openssl x509 -req -days 36500 -in HF_Bank_IT.csr -signkey HF_Bank_IT.key -out HF_Bank_IT.crt 

6.4.1.3 使用Keytool

keytool -export -alias hf-bank-it -keystore HF_Bank_IT.jks -rfc -file HF_Bank_IT.cer

6.4.2 导出服务端证书和密钥库

6.4.2.1 使用XCA导出服务端证书和密钥库

在XCA中选中服务端证书,点击“导出”按钮,选择导出DER格式的证书,用于客户端(如浏览器)安装或自动下载。
Java加解密(八)数字证书_第19张图片
再点击一次“导出”按钮,选择导出p12格式密钥库,包括证书链和私钥,用作服务器端(如Tomcat)的密钥库:
Java加解密(八)数字证书_第20张图片

6.4.2.2 使用OpenSSL导出服务端证书和密钥库

参见5.3节

6.4.2.3 使用Keytool导出服务端证书和密钥库

参见5.3节

6.4.3 导出客户端证书和密钥库

6.4.3.1 使用XCA导出客户端证书和密钥库

在XCA中选中客户端证书,点击“导出”按钮,选择导出DER格式的证书,用于服务器(如Tomcat)安装可信证书。
Java加解密(八)数字证书_第21张图片
再点击一次“导出”按钮,选择导出p12格式密钥库,包括证书链和私钥,用作客户端(浏览器)密钥导入:
Java加解密(八)数字证书_第22张图片

6.4.3.2 使用OpenSSL导出客户端证书和密钥库

参见5.3节

6.4.3.3 使用Keytool导出客户端证书和密钥库

参见5.3节

7 作废证书

**证书吊销列表(Certificate Revocation List,CRL)**一个被签署的列表,它指定了一套证书发布者认为无效的证书。除了普通CRL外,还定义了一些特殊的CRL类型用于覆盖特殊领域的CRL。

CRL一定是被CA所签署的,可以使用与签发证书相同的私钥,也可以使用专门的CRL签发私钥。CRL中包含了被吊销证书的序列号。

证书具有一个指定的寿命,但CA可通过称为证书吊销的过程来缩短这一寿命。CA发布一个证书吊销列表 (CRL),列出被认为不能再使用的证书的序列号。CRL 指定的寿命通常比证书指定的寿命短得多。CA也可以在CRL中加入证书被吊销的理由。它还可以加入被认为这种状态改变所适用的起始日期。

可将下列情况指定为吊销证书的理由:

  • 泄露密钥
  • 泄露 CA
  • 从属关系改变
  • 被取代
  • 业务终止

由CA吊销证书意味着,CA在证书正常到期之前撤销其允许使用该密钥对的有关声明。在吊销的证书到期之后,CRL 中的有关条目被删除,以缩短CRL列表的大小。

在验证签名期间,应用程序可以检查CRL,以确定给定证书和密钥对是否仍然可信(有些应用程序使用 CryptoAPI 中的 Microsoft 证书链验证 API 来完成此任务)。如果不可信,应用程序可以判断吊销的理由或日期对使用有疑问证书是否有影响。如果该证书被用来验证签名,且签名的日期早于CA吊销该证书的日期,那么该签名仍被认为是有效的。

应用程序获得CRL之后,由客户机缓存CRL,在它到期之前客户机将一直使用它。如果CA发布了新的CRL,拥有有效CRL的应用程序并不使用新的CRL,直到应用程序拥有的CRL到期为止。

公钥证书中会写出该证书的CA中心CRL地址。

8 证书的存储格式

证书涉及很多编码规范,持久化到文件后,一般以不同的文件名区分不同的编码格式。

8.1 证书的编码规范

ASN.1(Abstract Syntax Notation dotone),抽象语法标记1。

ASN.1(Abstract Syntax Notation dotone),抽象语法标记1。是定义抽象数据类型形式的标准,描绘了与任何表示数据的编码技术无关的通用数据结构。抽象语法使得人们能够定义数据类型,并指明这些类型的值。抽象语法只描述数据的结构形式,与具体的编码格式无关,同时也不涉及这些数据结构在计算机内如何存放。

X.690

X.690就是一个ITU-T的标准,它里面包含了一些对ASN.1进行编码的规则。

X.690主要包含了Basic Encoding Rules (BER),Canonical Encoding Rules (CER)和Distinguished Encoding Rules (DER)这三种编码规则。

  • BER(Basic Encoding Rules)它是最早的编码规则,使用Tag-Length-Value(TLV)的格式对所有信息进行编码。
  • CER(Canonical Encoding Rules),还有DER,这两个编码都是从BER衍生过来的,他们都是BER的变体,可以说是BER的扩展和实现。CER和DER相比,CER使用的是不确定长度的格式,而DER使用的是确定长度的格式。
  • DER(Distinguished Encoding Rules),DER 是ASN.1 众多编码方案中的一个。DER 是 BER 的子集,对数据产生一个唯一的序列化表示。DER格式的内容是二进制形式。DER被广泛使用在数字证书中,比如X.509。

8.2 证书文件格式

证书数据需要存储和交换,需要生成证书文件,就会涉及到加密和编码。

X.509规定多种常用的证书文件扩展名。不过其中的一些还用于其它用途,就是说具有这个扩展名的文件可能并不是证书,比如说可能只是保存了私钥。

PEM(Privacy-Enhanced Mail,隐私增强邮件)是一种容器格式,可以将DER编码的证书再进行Base64编码后的数据存放在证书证书文件中,除了证书,还支持证书链,私钥。

PKCS(The Public-Key Cryptography Standards )是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。

  • PKCS#7,公钥标准,也叫做加密消息的语法标准,由RSA安全体系在公钥加密系统中交换数字证书产生的一种加密标准。
  • PKCS#8,私钥标准,描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。
  • PKCS#10,CSR标准,描述证书请求(CSR)语法标准,证书请求包含了一个唯一识别名、公钥和可选的一组属性,它们一起被请求证书的实体签名。
  • PKCS#12,是一种交换数字证书的加密标准,用来描述个人身份信息。如:用户公钥、私钥、证书等。
  • PFX,PKCS#12之前的格式(通常用PKCS#12格式,比如那些由IIS产生的PFX文件)
文件扩展名 编码规则 数据格式 内容 样例
.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

9 部署HTTPS双向认证

HTTP 由于是明文传输,主要存在三大风险:窃听风险、篡改风险、冒充风险

HTTPS 就是为了解决上述三个风险而生的,一般我们认为安全的通信需要包括以下四个原则: 机密性、完整性,身份认证,不可否认

HTTPS (全称:Hypertext Transfer Protocol Secure),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。HTTPS 在HTTP 的基础下加入SSL,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面 。

  • SSL(Secure Socket Layer,安全套接字层):1994年为 Netscape 所研发,SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。
  • TLS(Transport Layer Security,传输层安全):其前身是 SSL,它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,1999年从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。SSL3.0和TLS1.0由于存在安全漏洞,已经很少被使用到。TLS 1.3 改动会比较大,目前还在草案阶段,目前使用最广泛的是TLS 1.1、TLS 1.2。

TLS利用密钥算法在互联网上提供端点身份认证与通讯保密,其基础是公钥基础设施(public key infrastructure,PKI),证书为TLS协议中加密算法的公钥的安全传输提供了解决方案。不过在实现的典型例子中,只有网络服务者被可靠身份验证(单向认证),而其客户端(双向认证)则不一定。这是因为公钥基础设施普遍商业运营,证书通常需要付费购买。

在智能手机普及之前,银行如何实现HTTPs双向认证的 ?通常会提供给客户一个U盾,只有在插入U盾的电脑上才能进行转账操作。其实原理也是在U盾中添加了密钥库和和客户端证书,用来认证客户身份。但这种方案成本很高,每一个客户都需要一个独立的U盾。

下面我们以一个实际的Springboot项目的例子来看如何配置双向认证的HTTPS连接。

9.1 创建SpringBoot的项目

首先创建一个空的SpringBoot项目。

9.2 部署HTTPS双向认证

总结一下涉及到的所有证书和密钥库:

文件 描述 安装位置
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的密钥库

9.2.1 部署服务端

1 导入CA根证书到信任密钥库(trust keystore)

服务端用来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>
2 导入客户端证书到信任密钥库(trust keystore)

这一步是将客户端证书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>

这条命令做了两件事情:

  1. 创建信任密钥库文件:trust-key-store.jks
  2. 将客户端证书导入新人密钥库

完毕后可以运行如下命令查看密钥库中的证书,确认安装成功。现在信任密钥库中应该有两个证书。

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>
3 添加密钥库文件

新建文件夹:src\main\resources\certs,将密钥库拷贝到文件夹下:
src\main\resources\certs\HF_Commercial_Bank.p12
src\main\resources\certs\trust-key-store.jks

4 添加HTTPS profile

添加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"/>
5 添加Controller

这个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;
    }
}
6 添加Redirec配置

这个类将客户端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;
    }
}

最终的项目看起来像这样:
Java加解密(八)数字证书_第23张图片

9.2.2 部署客户端

1 安装CA根证书

这一步是模仿权威CA根证书,将自签名CA根证书倒入客户端系统,成为可信任的CA根证书。
在Windows中双击证书文件:HF_Bank_IT.cer进行安装,安装完成后在浏览器的证书管理中可以看到已添加到受信列表:
Java加解密(八)数字证书_第24张图片

2 安装客户端密钥库

这一步是安装客户端证书和私钥到客户端系统。
在Windows中双击密钥库文件:HF_Commercial_Bank_client.p12进行安装,安装完成后在浏览器的证书管理中可以看到已添加到个人证书:
Java加解密(八)数字证书_第25张图片

如果缺少了以上步骤,就会在浏览器中看到客户端证书校验失败的错误。
Java加解密(八)数字证书_第26张图片

9.2.3 运行程序

构建并运行程序,访问链接:https://localhost:8443/health,浏览器会提示选择认证的证书。
Java加解密(八)数字证书_第27张图片
选择安装的客户端证书,点击“确定”按钮,成功收回相应,打印出客户端证书的详情:
Java加解密(八)数字证书_第28张图片
至此,双向HTTPS部署成功。

你可能感兴趣的:(java,java,开发语言)